mirror of
https://github.com/ziglang/zig.git
synced 2024-11-26 14:20:25 +00:00
0fe3fd01dd
The compiler actually doesn't need any functional changes for this: Sema does reification based on the tag indices of `std.builtin.Type` already! So, no zig1.wasm update is necessary. This change is necessary to disallow name clashes between fields and decls on a type, which is a prerequisite of #9938.
113 lines
2.7 KiB
Zig
113 lines
2.7 KiB
Zig
const expect = @import("std").testing.expect;
|
|
const mem = @import("std").mem;
|
|
|
|
// Declare an enum.
|
|
const Type = enum {
|
|
ok,
|
|
not_ok,
|
|
};
|
|
|
|
// Declare a specific enum field.
|
|
const c = Type.ok;
|
|
|
|
// If you want access to the ordinal value of an enum, you
|
|
// can specify the tag type.
|
|
const Value = enum(u2) {
|
|
zero,
|
|
one,
|
|
two,
|
|
};
|
|
// Now you can cast between u2 and Value.
|
|
// The ordinal value starts from 0, counting up by 1 from the previous member.
|
|
test "enum ordinal value" {
|
|
try expect(@intFromEnum(Value.zero) == 0);
|
|
try expect(@intFromEnum(Value.one) == 1);
|
|
try expect(@intFromEnum(Value.two) == 2);
|
|
}
|
|
|
|
// You can override the ordinal value for an enum.
|
|
const Value2 = enum(u32) {
|
|
hundred = 100,
|
|
thousand = 1000,
|
|
million = 1000000,
|
|
};
|
|
test "set enum ordinal value" {
|
|
try expect(@intFromEnum(Value2.hundred) == 100);
|
|
try expect(@intFromEnum(Value2.thousand) == 1000);
|
|
try expect(@intFromEnum(Value2.million) == 1000000);
|
|
}
|
|
|
|
// You can also override only some values.
|
|
const Value3 = enum(u4) {
|
|
a,
|
|
b = 8,
|
|
c,
|
|
d = 4,
|
|
e,
|
|
};
|
|
test "enum implicit ordinal values and overridden values" {
|
|
try expect(@intFromEnum(Value3.a) == 0);
|
|
try expect(@intFromEnum(Value3.b) == 8);
|
|
try expect(@intFromEnum(Value3.c) == 9);
|
|
try expect(@intFromEnum(Value3.d) == 4);
|
|
try expect(@intFromEnum(Value3.e) == 5);
|
|
}
|
|
|
|
// Enums can have methods, the same as structs and unions.
|
|
// Enum methods are not special, they are only namespaced
|
|
// functions that you can call with dot syntax.
|
|
const Suit = enum {
|
|
clubs,
|
|
spades,
|
|
diamonds,
|
|
hearts,
|
|
|
|
pub fn isClubs(self: Suit) bool {
|
|
return self == Suit.clubs;
|
|
}
|
|
};
|
|
test "enum method" {
|
|
const p = Suit.spades;
|
|
try expect(!p.isClubs());
|
|
}
|
|
|
|
// An enum can be switched upon.
|
|
const Foo = enum {
|
|
string,
|
|
number,
|
|
none,
|
|
};
|
|
test "enum switch" {
|
|
const p = Foo.number;
|
|
const what_is_it = switch (p) {
|
|
Foo.string => "this is a string",
|
|
Foo.number => "this is a number",
|
|
Foo.none => "this is a none",
|
|
};
|
|
try expect(mem.eql(u8, what_is_it, "this is a number"));
|
|
}
|
|
|
|
// @typeInfo can be used to access the integer tag type of an enum.
|
|
const Small = enum {
|
|
one,
|
|
two,
|
|
three,
|
|
four,
|
|
};
|
|
test "std.meta.Tag" {
|
|
try expect(@typeInfo(Small).@"enum".tag_type == u2);
|
|
}
|
|
|
|
// @typeInfo tells us the field count and the fields names:
|
|
test "@typeInfo" {
|
|
try expect(@typeInfo(Small).@"enum".fields.len == 4);
|
|
try expect(mem.eql(u8, @typeInfo(Small).@"enum".fields[1].name, "two"));
|
|
}
|
|
|
|
// @tagName gives a [:0]const u8 representation of an enum value:
|
|
test "@tagName" {
|
|
try expect(mem.eql(u8, @tagName(Small.three), "three"));
|
|
}
|
|
|
|
// test
|