据我所知:在C语言中,变量的“类型”在编译期间被绑定,并且该变量的值在运行时被绑定。
例如,在int a = 10;
中,类型int
在编译期间绑定到变量a
,并且实际值10
被绑定(或分配)给它在运行期间。
但在Rust,我们有let a = 2;
。这里,何时类型(来自Rust中任何整数类型的i32
)都绑定到a
?
我正在构建一个前端Rust编译器,目前正在编写解析器阶段。此时,我应该为这些变量分配什么类型?
答案 0 :(得分:5)
类型绑定在编译时执行。这是必要的,以便编译器可以发出正确的机器指令(例如,x86_64
处理器不会乘以两个i32
,就像它乘以两个i64
s的方式相同。
许多动态类型语言(如Python或Lua)将携带类型信息以及值(不变量),并根据每个操作数的类型在运行时调度操作。另一方面,静态类型的语言,如C或Rust,通常会丢弃大多数类型信息;它不是必需的,因为执行操作所需的机器指令直接在可执行文件中发出(这使得静态类型的程序比可比较的动态类型程序更快)。
我们可以通过让编译器告诉我们类型错误(这称为类型检查)来证明类型绑定是在编译时完成的。这是一个例子:
fn squared(x: f64) -> f64 {
x * x
}
fn main() {
let a = 2i32;
println!("{}", squared(a));
}
编译它会得到以下输出:
error[E0308]: mismatched types
--> src/main.rs:7:28
|
7 | println!("{}", squared(a));
| ^ expected f64, found i32
Rust编译器可以根据用法推断许多变量的类型(类似于auto
在C ++中的工作方式)。如果不能,它会给出错误。例如:
fn main() {
let a;
}
给出了这个输出:
error[E0282]: type annotations needed
--> src/main.rs:2:9
|
2 | let a;
| ^
| |
| cannot infer type for `_`
| consider giving `a` a type
当编译器遇到错误时,它会停止并且不会产生可运行的可执行文件。由于我们没有可执行的程序形式,因此没有"运行时间",所以上述情况发生在编译时。