Rust 中,变量默认是不可修改的,这正是 Rust 考虑内存的安全性所推崇的性质之一。然而,我们仍然方法可以修改变量的值。当一个变量被定义后,因为其不可变性(immutable),为了阐明这一点,我们创建一个项目来仔细讨论。
创建新项目
使用 Cargo 来创建项目:
$ cargo new variables
变量的不可变和可变(immutable & mutable)
不可变变量(immutable)
添加以下代码:
fn main() {
let x = 5;
println!("x: {}", x);
x = 10;
println!("x: {}", x);
}
使用cargo check
检查代码,我们会发现报错:
报错信息提示我们,"cannot assign twice to immutable variable",即不能声明两次不可变变量。编译报错尝尝令人沮丧,但是在这里,编译器仅仅是因为变量不够安全而报错,Rust 一向注重内存安全,因此,如此严格的内存管理措施,可以避免很多项目在内存上的错误。因为未期望的变量更改常常引发一些隐性的 bug ,并且这么 bug 不容易被定位。如果将变量默认设置为不可变,则避免了很多类似的 bug,使得调试程序变得简单高效。
可变变量(mutable)
我们在定义变量时,在变量名前面添加mut
关键字,即表示这个变量是可变变量:
fn main() {
let mut x = 5;
println!("x: {}", x);
x = 10;
println!("x: {}", x);
}
使用cargo check
检查代码发现代码并没有报错,这证明我们被允许修改变量的值。
常量(constants)
常量就像地球的重力加速度、光速(物理值在理想情况下讨论)是不可变的。
常量和变量存在不同,在常量中,不允许出现mut
关键字,也就意味着常量一旦被定义,则不可更改。
用const
关键字来定义常量。
const THREE_HOURS_IN_SECONDS: u32 = 3 * 60 * 60;
这里我们使用全大写来定义常量,若我们尝试用小写来定义常量,编译器会出现警告:
它提示我们要用大写字母来定义常量。
遮蔽(shadowing)
Rust 中,允许我们定义一个和之前变量名相同的变量。
fn main() {
let x = 5;
let x = 10;
}
从运行结果来看,代码并未出现任何警告或者报错。
因为在 Rust 中,将此操作视为遮蔽,即遮盖了之前的变量,用新的变量来取代,这允许我们变相修改不可变变量。
虽然这种方式看起来很奇怪,但却有效地提示我们谨慎地修改变量值。
在遮蔽中,我们不止被允许修改变量的值,还可以对其赋值不同类型的值。
let spaces = " ";
let spaces = spaces.len();
变量域(scope)
fn main() {
let x = 5;
println!("x: {}", x);
{
let x = x + 20;
println!("x(inner scope): {}", x);
}
let x = 10;
println!("x: {}", x);
}
这段代码展示了变量的域,我们首先定义了变量x
,然后在打括号内又定义了变量x
,在大括号内,第一次使用和外界同名的变量时,会取外界变量的值,而后,会用内部变量的值来代替同名变量的值,这种机制,避免了我们使用复杂冗长的操作来传递变量,在实际编程中很有用。