Rust 什么时候发生类型绑定?
When does type binding happen in Rust?
据我所知:在C语言中,变量的"type"在编译时绑定,变量的值在运行时绑定。
例如,在int a = 10;
中,类型int
在编译时绑定到变量a
,实际值10
被绑定(或赋值)在 运行 时间内。
但是在 Rust 中,我们有 let a = 2;
。在这里,类型(比如 Rust 中任何整数类型的 i32
)何时绑定到 a
?
我正在构建前端 Rust 编译器,目前正在编写解析器阶段。此时,我应该为这些变量分配什么类型?
类型绑定在编译时执行。这是必要的,这样编译器才能发出正确的机器指令(例如,x86_64
处理器不会像乘两个 i64
那样乘以两个 i32
)。
许多 dynamically-typed 语言,例如 Python 或 Lua,将携带类型信息和值(不是 变量)并根据每个操作数的类型在运行时分派操作。另一方面,statically-typed 语言,例如 C 或 Rust,通常会丢弃大部分类型信息;这不是必需的,因为执行操作所需的机器指令直接在可执行文件中发出(这使得 statically-typed 程序比可比较的 dynamically-typed 程序更快)。
我们可以通过让编译器告诉我们类型错误(这称为 类型检查)来证明类型绑定是在编译时完成的。这是一个例子:
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
当编译器遇到错误时,它会停止并且不会生成可运行的可执行文件。由于我们没有程序的可执行形式,因此没有 "run time",因此上述情况发生在编译时。
据我所知:在C语言中,变量的"type"在编译时绑定,变量的值在运行时绑定。
例如,在int a = 10;
中,类型int
在编译时绑定到变量a
,实际值10
被绑定(或赋值)在 运行 时间内。
但是在 Rust 中,我们有 let a = 2;
。在这里,类型(比如 Rust 中任何整数类型的 i32
)何时绑定到 a
?
我正在构建前端 Rust 编译器,目前正在编写解析器阶段。此时,我应该为这些变量分配什么类型?
类型绑定在编译时执行。这是必要的,这样编译器才能发出正确的机器指令(例如,x86_64
处理器不会像乘两个 i64
那样乘以两个 i32
)。
许多 dynamically-typed 语言,例如 Python 或 Lua,将携带类型信息和值(不是 变量)并根据每个操作数的类型在运行时分派操作。另一方面,statically-typed 语言,例如 C 或 Rust,通常会丢弃大部分类型信息;这不是必需的,因为执行操作所需的机器指令直接在可执行文件中发出(这使得 statically-typed 程序比可比较的 dynamically-typed 程序更快)。
我们可以通过让编译器告诉我们类型错误(这称为 类型检查)来证明类型绑定是在编译时完成的。这是一个例子:
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
当编译器遇到错误时,它会停止并且不会生成可运行的可执行文件。由于我们没有程序的可执行形式,因此没有 "run time",因此上述情况发生在编译时。