在 Rust 中, 变量可以具有下面的属性。
Rust 的安全哲学要求变量默认是不可变的。
fn main() {
// 定义一个不可变的变量
let x = 5;
// 错误: cannot assign twice to immutable variable `x`
// x = 6;
// 定义一个可变的变量
let mut y = 5;
// 正确。可以改变!
y = y + 1;
println!("{}", x + y);
}
重定义(遮蔽)特性是一个 Rust 特有的语言特性。 相对于可变变量,重定义(遮蔽)一个变量,可以改变原有变量的数据类型和可变性。
fn main() {
// 定义一个不可变的变量
let x = 5;
// 重定义变量 x。注意:变量类型和可变性都可以变。
// 变量 x 从整数数据类(i32)型变成了字符串数据类型(String)。
// 变量 x ,因为声明了 mut ,可变性也变成可变的。
let mut x: String = (x + 1).to_string();
// 正确。可以改变!
x = x + ":1";
println!("{}", x);
}
重定义特性的其它特点:
常量的一个非常重要的特点是: 它的值会在编译时被 copy 到使用的地方。 注意:这种 copy 也会发生在外部包被编译的场合。因此,一定要确保你的常量不会在后续的开发中发生变化。
一个静态变量在应用中拥有唯一的内存地址。 大多数场合,静态变量会被定义为可变的。 在 Rust 的安全哲学中静态变量不是线程安全的,所以可变的静态变量在被读和写的场合,都需要标识 unsafe。
// 定义一个可变的静态变量
static mut LEVEL: i32 = 5;
// 定义一个不可变的静态变量
static CORRECT: i32 = 1;
fn main() {
// 错误: note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
LEVEL = LEVEL + 1;
// 错误: note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
println!("{}", LEVEL);
// 正确: 不可变的静态变量是线程安全的。
println!("{}", CORRECT);
// 读写静态变量都需要在unsafe中
unsafe {
// LEVEL = LEVEL + 1;
println!("{}", LEVEL);
}
}
那么,什么时候使用静态变量?什么时候使用常量呢?