Learning Zig from the official language reference.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
zig-langref/enums.zig

113 lines
3.1 KiB

const std = @import("std");
const mem = std.mem;
const debug = std.debug;
const testing = std.testing;
const Type = enum {
ok,
not_ok,
};
const c = Type.not_ok;
const Value = enum(u2) { zero, one, two };
// we can extract ordinal values only if the tag type has been specified, and is an integral type
test "enum ordinal value" {
testing.expect(@enumToInt(Value.zero) == 0);
testing.expect(@enumToInt(Value.one) == 1);
testing.expect(@enumToInt(Value.two) == 2);
}
const Value2 = enum(u32) { one = 1, hundred = 100, million = 1_000_000 };
test "custom ordinal values" {
testing.expect(@enumToInt(Value2.one) == 1);
testing.expect(@enumToInt(Value2.hundred) == 100);
testing.expect(@enumToInt(Value2.million) == 1_000_000);
}
const Suit = enum {
clubs,
diamonds,
spades,
hearts,
pub fn isClubs(self: Suit) bool {
return self == Suit.clubs;
}
};
test "enum methods" {
const clubs = Suit.clubs;
testing.expect(Suit.isClubs(clubs));
testing.expect(clubs.isClubs()); // this works
const clubs1 = .clubs;
testing.expect(Suit.isClubs(clubs1));
// this does not work due to the literal
//testing.expect(clubs1.isClubs());
}
const Foo = enum { string, number, none };
test "switching on enums" {
const p = Foo.number;
const what_is_it = switch (p) {
Foo.string => "a string",
Foo.number => "a number",
Foo.none => "a none",
};
testing.expect(mem.eql(u8, "a number", what_is_it));
const pp = Foo.none;
const what_is_it_again = switch (pp) {
.string => "a string",
.number => "a number",
.none => "nothing",
};
testing.expect(mem.eql(u8, "nothing", what_is_it_again));
}
const Small = enum { one, two, three, four, five };
test "typeInfo to get the tag type of an enum" {
testing.expect(@typeInfo(Small).Enum.tag_type == u3); // the smallest size that can hold the variants
}
// @typeInfo is extremely useful for reflective metaprogramming
test "@typeInfo" {
testing.expect(@typeInfo(Small).Enum.fields.len == 5);
testing.expect(mem.eql(u8, "one", @typeInfo(Small).Enum.fields[0].name));
testing.expect(mem.eql(u8, "two", @typeInfo(Small).Enum.fields[1].name));
testing.expect(mem.eql(u8, "three", @typeInfo(Small).Enum.fields[2].name));
testing.expect(mem.eql(u8, "four", @typeInfo(Small).Enum.fields[3].name));
testing.expect(mem.eql(u8, "five", @typeInfo(Small).Enum.fields[4].name));
}
test "@tagName" {
testing.expect(mem.eql(u8, "one", @tagName(Small.one)));
testing.expect(mem.eql(u8, @tagName(Small.three), @typeInfo(Small).Enum.fields[2].name));
}
// normal enums are not compatible with the C ABI. use extern enums for that.
// packed enums also seem to work just fine (though there may be caveats).
//const Bar = enum { a, b, c };
const Bar = extern enum { a, b, c };
export fn entry(bar: Bar) void {}
const Baz = packed enum(u3) { a, b, c, d, e };
test "packed enums" {
testing.expect(@sizeOf(Baz) == @sizeOf(u3));
const Quux = packed enum(u32) {
zero,
};
testing.expect(@sizeOf(Quux) == @sizeOf(u32));
}