我使用的是 Zig 0.14.dev,我想获得一个带有默认值的环境变量。 docs 说如果变量不存在,则会引发错误。现在,如果出现任何其他错误(例如
OutOfMemory
),我希望它传播。
const std = @import("std");
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
const db_path = std.process.getEnvVarOwned(allocator, "DB_PATH") catch |err| {
if (err == std.process.GetEnvVarOwnedError.EnvironmentVariableNotFound) {
return "/path";
} else {
return err;
}
};
std.debug.print("path: {s}\n", .{db_path});
}
这给了我这个错误:
src/main.zig:11:20: error: expected type '@typeInfo(@typeInfo(@TypeOf(main.main)).@"fn".return_type.?).error_union.error_set!void', found '*const [5:0]u8'
return "/path";
^~~~~~~
src/main.zig:4:16: note: function return type declared here
pub fn main() !void {
^~~~
我怎样才能正确地做到这一点?
如果你想从
catch
“返回”一个值,你不能使用return
,它会从函数中返回,但函数不能返回字符串;它的返回类型是!void
。
您可以使用带有
break
的标记块:
const db_path = ... catch |err| blk: {
if (...) {
break :blk "/path";
} else {
return err;
}
};
标签的名称是任意的,
blk
经常按约定使用。
请注意,您不必完全限定错误的名称,因为它已添加到全局错误集中,您可以通过
error.EnvironmentVariableNotFound
引用它。
使用
switch
代替 if
也可以使代码更加紧凑:
const db_path = ... catch |err| blk: {
switch (err) {
error.EnvironmentVariableNotFound => break :blk "/path",
else => return err,
}
};