【发布时间】:2016-10-19 01:04:11
【问题描述】:
我了解到,如果一个变量没有使用mut 显式声明为可变的,它就会变成不可变的(声明后不能更改)。那么为什么我们在 Rust 中有 const 关键字呢?他们不一样吗?如果不是,它们有何不同?
【问题讨论】:
标签: rust constants immutability
我了解到,如果一个变量没有使用mut 显式声明为可变的,它就会变成不可变的(声明后不能更改)。那么为什么我们在 Rust 中有 const 关键字呢?他们不一样吗?如果不是,它们有何不同?
【问题讨论】:
标签: rust constants immutability
从概念上讲,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(),
}
【讨论】:
const 不代表一个内存位置,而是一个值。 const 值直接内联在使用位置。在表达式求值期间创建的任何临时对象只能由编译器在编译期间访问。可以在全球范围内。无法引用运行时项。必须进行类型注释。
让值代表一个内存位置。 let 绑定的不变性是编译器强制执行的,可以使用 mut 修饰符进行更改。它是运行时构造。始终在本地范围内。它们的类型可以由编译器推断出来。
为了完整起见,static 也表示像 let 一样的内存位置,但对同一静态的任何引用实际上都是对同一内存位置的引用。静态是静态的。它们被编译成可执行文件,并且在运行程序的整个生命周期内都可以访问。可以在全球范围内。可以参考其他静力学。必须进行类型注释。
【讨论】:
此外,我们不能使用 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、static 和 let 用法的更多信息:
const and static
故事有点长。
【讨论】:
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)的另一种用法在这里不讨论。
【讨论】:
常量不能重新定义:
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 不适用于变量;它用于可能不会存储在任何地方的常量值;它们实际上是文字值的别名。
非mut let 声明了一个在运行时创建的实际变量,可以移动(并且不再可访问),甚至在某些情况下具有内部可变性(例如,如果它包含Cell 成员)案例。
【讨论】:
const 用于编译时常量以及所需的一切。例如,您可以创建一个大小为const 的固定大小的数组,但您不能使用let 绑定来做到这一点。当然,这也意味着您可以在let 绑定中放入比const 更多的东西。
【讨论】: