我了解到,如果变量未使用mut
显式声明为可变,则变为不可变(声明后无法更改)。那么为什么我们在Rust中有const
个关键字?他们不一样吗?如果没有,它们有何不同?
答案 0 :(得分:25)
const
是常量的缩写,与编译时评估相关。它出现了:
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
),此处不再讨论。
答案 1 :(得分:12)
const
不适用于变量;这是恒定值,可能无法存储在任何地方;它们实际上是字面值的别名。
非mut
let
声明一个在运行时创建的实际变量,可以移动(并且不再可访问),甚至具有内部可变性(如果它包含Cell
个成员,例如)在某些情况下。
答案 2 :(得分:3)
const
并不代表存储位置,而是一个值。 const
个值直接在使用位置内联。在表达式求值期间创建的任何临时对象只能由编译器在编译期间访问。可以全局作用域。无法引用运行时项目。必须输入注释。
让值代表一个存储位置。 let
绑定的不变性是编译器强制执行的事情,可以使用mut
修饰符进行更改。它是运行时构造。始终在本地范围内。它们的类型可以由编译器推断。
出于完整性考虑,static
还表示一个类似于let的存储位置,但是对同一静态的任何引用实际上都是对同一存储位置的引用。静态是静态。它们被编译为可执行文件,并且在运行程序的整个生命周期中都可以访问。可以全局作用域。可以引用其他静态变量。必须输入注释。
答案 3 :(得分:1)
const
用于包含所有内容的编译时常量。例如,您可以创建一个大小为const
的固定大小的数组,但是您无法使用let
绑定执行此操作。当然,这也意味着您可以将更多内容放入let
绑定中而不是放入const
。
答案 4 :(得分:1)
不能重新定义常量:
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
答案 5 :(得分:0)
此外,我们不能使用 let 来创建全局项,但是可以使用 const 来创建全局项。这是一个例子。
const LENGTH:usize = 4;
fn main() {
let arr:[i32; LENGTH] = [10,20,30,40];
for i in 0..LENGTH{
println!("{}", arr[i])
}
}
有关 const ,静态和 let 用法的更多信息:
const
and static
这个故事有点长。