为什么 zig 中的用户定义类型需要是常量?
why do user defined types in zig need to be const?
如果我需要在 Zig 中声明一个结构,我必须在它前面加上 const
const Arith = struct {
x: i32,
y: i32,
fn add(self: *Arith) i32 {
return self.x + self.y;
}
};
test "struct test" {
var testArith = Arith{
.x = 9,
.y = 9,
};
expect(testArith.add() == 18);
}
但是它可以用 var
和 const
两种方式初始化,所以为什么类型声明需要一个常量关键字,而结构的实例是否是 const
才重要还是不?
由于 Arith
属于 type
类型,因此必须将其声明为常量,因为编译器希望它是。这可以通过将类型声明更改为此和 运行 程序
来检查
var Arith = struct {
x: i32,
y: i32,
fn add(self: *Arith) i32 {
return self.x + self.y;
}
};
这将导致错误 error: variable of type 'type' must be constant
同样在 Zig 中,我们需要在名称前加上 const
或 var
,否则它会被视为无效标记。
需要 const
因为根作用域中的求值顺序未定义,而且 type
类型的变量只能存在于编译器中(没有内存表示,编译器是无法生成它的二进制表示)。但是您可以在其他范围内使用 var
:
comptime {
var T = struct { value: u64 };
const x: T = .{ .value = 3 };
T = struct { ok: bool };
const y: T = .{ .ok = true };
@compileLog(x.value); // <- 3
@compileLog(y.ok); // <- true
}
其余的回答,我会详细说明。
常量
const Arith = struct {...};
创建一个推断类型的常量变量。在这种情况下,变量 Arith
的类型为 type
:
const Arith = struct {...};
comptime {
@compileLog(@TypeOf(Arith)); // <- type
}
这与将变量声明为相同:
const Arith: type = struct {...};
变量
您也可以使用 var
创建一个变量
示例:
comptime {
var Arith = struct {...};
}
comptime {
var Arith: type = struct {...};
}
fn main() !void {
comptime var Arith = struct {...};
}
fn main() !void {
var Arith: type = struct {...};
}
fn main() !void {
comptime var Arith: type = struct {...};
}
因为是一个变量你可以修改它:
comptime {
var T = u64;
T = bool;
@compileLog(T); // <-- bool
}
Comptime 类型
有些类型只能存在于编译器中,例如:type
或具有类型 anytype
或其他编译时间类型字段的结构。
在 type
的情况下,这会使编译器将 var x: type
解释为 comptime var x: type
。
然后,考虑以下代码:
var T = struct { value: u64 }; // <- Compiler error
comptime {
const x: T = .{ .value = 3 };
}
error: variable of type 'type' must be constant
因为根作用域中的计算顺序未定义,编译器强制在二进制文件中创建一个全局变量,但类型 type
没有内存表示。因此,编译器会引发错误。
如果我需要在 Zig 中声明一个结构,我必须在它前面加上 const
const Arith = struct {
x: i32,
y: i32,
fn add(self: *Arith) i32 {
return self.x + self.y;
}
};
test "struct test" {
var testArith = Arith{
.x = 9,
.y = 9,
};
expect(testArith.add() == 18);
}
但是它可以用 var
和 const
两种方式初始化,所以为什么类型声明需要一个常量关键字,而结构的实例是否是 const
才重要还是不?
由于 Arith
属于 type
类型,因此必须将其声明为常量,因为编译器希望它是。这可以通过将类型声明更改为此和 运行 程序
var Arith = struct {
x: i32,
y: i32,
fn add(self: *Arith) i32 {
return self.x + self.y;
}
};
这将导致错误 error: variable of type 'type' must be constant
同样在 Zig 中,我们需要在名称前加上 const
或 var
,否则它会被视为无效标记。
需要 const
因为根作用域中的求值顺序未定义,而且 type
类型的变量只能存在于编译器中(没有内存表示,编译器是无法生成它的二进制表示)。但是您可以在其他范围内使用 var
:
comptime {
var T = struct { value: u64 };
const x: T = .{ .value = 3 };
T = struct { ok: bool };
const y: T = .{ .ok = true };
@compileLog(x.value); // <- 3
@compileLog(y.ok); // <- true
}
其余的回答,我会详细说明。
常量
const Arith = struct {...};
创建一个推断类型的常量变量。在这种情况下,变量 Arith
的类型为 type
:
const Arith = struct {...};
comptime {
@compileLog(@TypeOf(Arith)); // <- type
}
这与将变量声明为相同:
const Arith: type = struct {...};
变量
您也可以使用 var
示例:
comptime {
var Arith = struct {...};
}
comptime {
var Arith: type = struct {...};
}
fn main() !void {
comptime var Arith = struct {...};
}
fn main() !void {
var Arith: type = struct {...};
}
fn main() !void {
comptime var Arith: type = struct {...};
}
因为是一个变量你可以修改它:
comptime {
var T = u64;
T = bool;
@compileLog(T); // <-- bool
}
Comptime 类型
有些类型只能存在于编译器中,例如:type
或具有类型 anytype
或其他编译时间类型字段的结构。
在 type
的情况下,这会使编译器将 var x: type
解释为 comptime var x: type
。
然后,考虑以下代码:
var T = struct { value: u64 }; // <- Compiler error
comptime {
const x: T = .{ .value = 3 };
}
error: variable of type 'type' must be constant
因为根作用域中的计算顺序未定义,编译器强制在二进制文件中创建一个全局变量,但类型 type
没有内存表示。因此,编译器会引发错误。