使用mem.无法计算常量表达式



谁能解释一下为什么这段代码不能编译?

const std = @import("std");
const ParseError = error { NotAValidField };
const TestEnum = enum {
field_1,
field_2,
pub fn fromString(str: []const u8) !TestEnum {
switch(true) {
std.mem.eql(u8, "field_1", str) => TestEnum.field_1,
std.mem.eql(u8, "field_2", str) => TestEnum.field_2,
else => ParseError.NotAValidField,
}
}
};
pub fn main() void {
const field = "field_1";
try TestEnum.fromString(field);
}

导致错误:

./example.zig:11:40: error: unable to evaluate constant expression
std.mem.eql(u8, "field_1", str) => TestEnum.field_1,

编译器是否试图在编译期间将str作为参数传递?下面是godbolt中的代码:https://zig.godbolt.org/z/reK6xv7h5

注:我已经知道有一个std.meta.stringToEnum函数。

编译器将mem.eql调用中的str视为运行时值,因此出现错误。要指定在运行时从不使用str,请添加comptime关键字,如下所示:

pub fn fromString(comptime str: []const u8) TestEnum {
return switch (true) {
std.mem.eql(u8, "field_1", str) => TestEnum.field_1,
std.mem.eql(u8, "field_2", str) => TestEnum.field_2,
};
}

请注意,所有这些都来自希望使用mem.eql结果来匹配true。这将枚举值的数量限制为两个,并要求在编译时知道该字符串。meta.stringToEnum所做的是在运行时执行操作。