我了解到,如果一个变量没有使用
mut
显式声明为可变的,它就会变得不可变(声明后不能更改)。那么为什么 Rust 中有 const
关键字呢?它们不是一样的吗?如果不是,它们有何不同?
const
,在 Rust 中是 constant 的缩写,与 编译时评估 相关。它显示:
const FOO: usize = 3;
const fn foo() -> &'static str
这些类型的值可以用作通用参数:
[u8; FOO]
。目前这仅限于数组大小,但有讨论、计划并希望将来进一步扩展。
相比之下,
let
绑定是关于运行时计算值的。
请注意,尽管使用
mut
是因为可变性的概念众所周知,但 Rust 实际上就在这里。 &T
和 &mut T
是关于别名,而不是可变性:
&T
:共享参考&mut T
:独特参考最值得注意的是,某些类型具有内部可变性,可以通过
&T
(共享引用)进行突变:Cell
、RefCell
、Mutex
等
注意:
mut
和const
与原始指针(*mut T
和*const T
)还有另一种用法,这里不讨论。
const
不适用于变量;它用于可能不存储在任何地方的常量值;它们实际上是文字值的别名。
Non-
mut
let
声明一个在运行时创建的实际变量,可以移动(并且不再可访问),甚至在某些情况下具有内部可变性(例如,如果它包含 Cell
成员)。
A
const
不代表内存位置,而是代表值。 const
值直接内联在其使用位置。在表达式求值期间创建的任何临时对象只能由编译器在编译时访问。可以在全球范围内进行。无法引用运行时项目。必须有类型注释。
让值代表一个内存位置。
let
绑定的不变性是编译器强制执行的,可以使用 mut
修饰符进行更改。它是运行时构造。始终在本地范围内。它们的类型可以由编译器推断。
为了完整起见,
static
也表示像let一样的内存位置,但对同一静态的任何引用实际上都是对同一内存位置的引用。静态就是静态。它们被编译为可执行文件,并在运行程序的整个生命周期内可访问。可以在全球范围内进行。可以参考其他静力学。必须有类型注释。
常量不能被遮蔽:
let x = 10u32;
const Y:u32 = 20u32;
let x = 11u32;
//error: duplicate definition of value `Y` [E0428]
//const Y:u32 = 21u32;
println!("x={} Y={}",x,Y); //x=11 Y=20
const
用于编译时常量及其所需的一切。例如,您可以创建一个大小为 const
的固定大小数组,但不能使用 let
绑定来做到这一点。当然,这也意味着您可以将更多的东西放入 let
绑定中,而不是放入 const
中。
从概念上讲,
const
项在解析之前被替换,类似于 C 宏的作用。这使得它可以在不允许使用普通变量的情况下使用。
const TEN: u32 = 10;
let ten = 10;
// OK
match x {
TEN => do_a(),
_ => do_b(),
}
// Nah...
match x {
ten => do_a(),
_ => do_b(),
}
// ...use this instead
match x {
y if x == ten => do_a(),,
_ => do_b(),
}