我是 Zig 的新手,正在尝试类型系统。我有一段代码执行一些 comptime 操作来确定张量的形状。我想使用这个 comptime 变量进行一些静态类型分析,并将其保留(目前)作为有用的运行时信息。我收到了错误:error: type capture contains reference to comptime var
我试图通过制作我认为它所说的较小版本来重现它,但尝试失败了。
我相信我收到的错误与这篇文章有关,其中的建议是:To fix the error, copy your finalized array to a const before taking a pointer.
我认为我的comptime_shape
是一个 const。我可以使用一些帮助来理解我上下文中的这个错误以及如何修复它:
const std = @import("std");
pub fn Tensor(comptime data: anytype) type {
const comptime_shape = getShape(@TypeOf(data));
return struct {
data: @TypeOf(data),
shape: [comptime_shape.len]usize,
const Self = @This();
pub fn init() Self {
return Self{ .data = data, .shape = comptime_shape };
}
};
}
fn getShape(comptime T: type) []const usize {
const info = @typeInfo(T);
switch (info) {
.Array => |arr| {
if (@typeInfo(arr.child) == .Array) {
const child_shape = getShape(arr.child);
var result: [child_shape.len + 1]usize = undefined;
result[0] = arr.len;
@memcpy(result[1..], child_shape);
return &result;
} else {
return &[_]usize{arr.len};
}
},
else => @compileError("Invalid tensor type"),
}
}
test "init tensor" {
const data: [2][3]f32 = .{ .{ 1, 2, 3 }, .{ 2, 3, 4 } };
const result = Tensor(data).init();
std.debug.print("tensor [{}]\n", .{result});
std.debug.print("tensor.shape [{}]\n", .{result.shape});
}
main.zig:6:12: error: type capture contains reference to comptime var
main.zig:37:26: note: called from here
对我来说这也非常有趣,如果我删除 const 数据的类型提示,那么我会收到一个全新的错误:
test "init tensor" {
const data = .{ .{ 1, 2, 3 }, .{ 2, 3, 4 } };
const result = Tensor(data).init();
std.debug.print("tensor [{}]\n", .{result});
std.debug.print("tensor.shape [{}]\n", .{result.shape});
}
main.zig:31:17: error: Invalid tensor type
main.zig:4:36: note: called from here
main.zig:37:26: note: called from here
comptime_shape
确实是 const,但它只是getShape
函数内部指向 comptime var 的一个指针。您可以通过按值返回数组来解决这个问题。您还需要创建第二个函数来计算此数组的大小:PS:函数
data
的参数Tensor
不必是comptime
。您只在 comptime 时使用它的类型,并且任何变量的类型始终是 comptime 已知的。我可能会将类型取出放入单独的函数中,并将数据作为运行时参数。但我可能遗漏了一些背景信息: