我编写了一个基本的命令调用包装函数,表面上看语法上似乎没问题。它基于Zig Cookbook中的一个示例,确实可以编译和运行。
然而,编译失败并出现一个我无法解决的错误,似乎(但可能并非真正)存在于标准库深处。
代码:
const std = @import("std");
const Child = std.process.Child;
const RunError = error {
Failed,
};
pub fn callCommand(alloc:std.mem.Allocator, command:[]const[]const u8) !std.ArrayList(u8) {
var caller = Child.init(command, alloc);
caller.stdout_behavior = .Pipe;
caller.stderr_behavior = .Pipe;
var stdout = std.ArrayList(u8).init(alloc);
var stderr = std.ArrayList(u8).init(alloc);
errdefer stdout.deinit();
defer stderr.deinit();
try caller.spawn(); // Error points to here...
try caller.collectOutput(&stdout, &stderr, 1024);
const res = try caller.wait();
if(res.Exited > 0) {
std.debug.print("{s}\n", stderr.items); // EDIT - this is the culprit, however
return RunError.Failed;
} else {
return stdout;
}
}
test {
const alloc = std.testing.allocator;
const out = try callCommand(alloc, &[_][]const u8{"ls", "-l"});
defer out.deinit();
std.debug.print("{s}\n", .{out.items});
}
尝试编译时:
$ zig test -freference-trace src/commands.zig
/home/tk-noodle/.local/var/zig/zig-linux-x86_64-0.13.0/lib/std/fmt.zig:88:9: error: expected tuple or struct argument, found []u8
@compileError("expected tuple or struct argument, found " ++ @typeName(ArgsType));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
print__anon_5241: /home/tk-noodle/.local/var/zig/zig-linux-x86_64-0.13.0/lib/std/io/Writer.zig:24:26
print: /home/tk-noodle/.local/var/zig/zig-linux-x86_64-0.13.0/lib/std/io.zig:324:47
print__anon_6636: /home/tk-noodle/.local/var/zig/zig-linux-x86_64-0.13.0/lib/std/debug.zig:97:21
unexpectedErrno: /home/tk-noodle/.local/var/zig/zig-linux-x86_64-0.13.0/lib/std/posix.zig:7319:24
setreuid: /home/tk-noodle/.local/var/zig/zig-linux-x86_64-0.13.0/lib/std/posix.zig:3372:30
spawnPosix: /home/tk-noodle/.local/var/zig/zig-linux-x86_64-0.13.0/lib/std/process/Child.zig:673:18
spawn: /home/tk-noodle/.local/var/zig/zig-linux-x86_64-0.13.0/lib/std/process/Child.zig:242:20
callCommand: src/commands.zig:18:15
test_0: src/commands.zig:35:21
具体来说,似乎在编译时会到达lib/std/posix.zig:3372:30
,从而将错误枚举传递给lib/std/posix.zig:7319:24
通过一些混乱,我确实确认了这.{@intFromEnum(err)}
可以解析为struct{u16}
,但不知何故,这被传递下来,最终导致错误,指出它看到一个[]u8
。
它表面上看起来像一个编译器问题,但如果我改变代码以返回!void
并简单地丢弃 stdout/stderr ,程序就会顺利编译,并且测试通过。
所以我的问题有两个:
- 我做错了什么导致这个错误?
- 为什么错误看起来像是指向 stdlib 中的问题,而不是我自己的代码?
在您的代码中:
这一行应该是: