I'm trying to iterate over all the fields in an Enum (really I just want to the values), in my enum
in Zig:
const std = @import("std");
const MyEnum = enum(u8) {
NONE = 0,
ONE,
TWO,
};
pub fn main() void {
std.debug.assert(@typeInfo(MyEnum).Enum.fields.len == 3);
std.debug.assert(std.mem.eql(u8, @typeInfo(MyEnum).Enum.fields[0].name, "NONE"));
std.debug.assert(@typeInfo(MyEnum).Enum.fields[0].value == 0);
for (std.meta.fields(MyEnum)) |f| {
std.debug.print("{}\n", .{ f.value });
}
for (@typeInfo(MyEnum).Enum.fields) |f| {
std.debug.print("{}\n", .{ f.value });
}
}
The asserts at the top just show I've got the basics right. Neither of the for
loops compile, I get:
... error: values of type '[]const builtin.Type.EnumField' must be comptime-known, but index value is runtime-known
AFAICT, all the content of the enum is "comptime-known", so I'm not sure why the error is complaining about EnumField
...
I'm running a locally-built zig 0.12.0-dev.1782+dd188307b sync'd in the last couple of days.
The error message is not very good because it's actually coming from your for
statement. It's the index that statement uses that's not comptime known. Use inline for
instead to run the loop at compile time:
const std = @import("std");
const MyEnum = enum(u8) {
NONE = 0,
ONE,
TWO,
};
pub fn main() void {
std.debug.assert(@typeInfo(MyEnum).Enum.fields.len == 3);
std.debug.assert(std.mem.eql(u8, @typeInfo(MyEnum).Enum.fields[0].name, "NONE"));
std.debug.assert(@typeInfo(MyEnum).Enum.fields[0].value == 0);
inline for (std.meta.fields(MyEnum)) |f| {
std.debug.print("{}\n", .{f.value});
}
inline for (@typeInfo(MyEnum).Enum.fields) |f| {
std.debug.print("{}\n", .{f.value});
}
}