enum
1/7 test "enum ordinal value"...OK
2/7 test "set enum ordinal value"...OK
3/7 test "enum method"...OK
4/7 test "enum variant switch"...OK
5/7 test "@TagType"...OK
6/7 test "@typeInfo"...OK
7/7 test "@tagName"...OK
All 7 tests passed.
See also:
By default, enums are not guaranteed to be compatible with the C ABI:
test.zig
const Foo = enum { A, B, C };
export fn entry(foo: Foo) void { }
$ zig build-obj test.zig
./docgen_tmp/test.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'
export fn entry(foo: Foo) void {
^
For a C-ABI-compatible enum, use extern enum
:
By default, the size of enums is not guaranteed.
packed enum
causes the size of the enum to be the same as the size of the integer tag type of the enum:
test.zig
const std = @import("std");
test "packed enum" {
One,
Two,
Three,
};
std.debug.assert(@sizeOf(Number) == @sizeOf(u8));
}
$ zig test test.zig
1/1 test "packed enum"...OK
All 1 tests passed.
This makes the enum eligible to be in a .
test.zig
$ zig test test.zig
1/2 test "enum literals"...OK
2/2 test "switch using enum literals"...OK
All 2 tests passed.
A Non-exhaustive enum can be created by adding a trailing '_' field. It must specify a tag type and cannot consume every enumeration value.
@intToEnum on a non-exhaustive enum cannot fail.
A switch on a non-exhaustive enum can include a '_' prong as an alternative to an else
prong with the difference being that it makes it a compile error if all the known tag names are not handled by the switch.
const std = @import("std");
const assert = std.debug.assert;
const Number = enum(u8) {
One,
_,
};
test "switch on non-exhaustive enum" {
const number = Number.One;
const result = switch (number) {
.One => true,
.Two,
.Three => false,
_ => false,
};
assert(result);
const is_one = switch (number) {
.One => true,
else => false,
};
assert(is_one);
}
$ zig test test.zig
1/1 test "switch on non-exhaustive enum"...OK