变量的不可变性
Rust中的变量默认是不可变的(immutable)。这是Rust语言设计的重要特性之一,有助于编写安全、并发的代码。
rust
fn main() {
let x = 5;
println!("The value of x is: {}", x);
x = 6; // 编译错误!不能对不可变变量二次赋值
println!("The value of x is: {}", x);
}
当我们尝试改变一个不可变变量的值时,Rust编译器会产生错误:
ini
error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:4:5
|
2 | let x = 5;
| - first assignment to `x`
3 | println!("The value of x is: {}", x);
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
2 | let mut x = 5;
| +++
这种设计有很多好处:
- 防止代码的一部分意外地更改另一部分代码期望不变的值
- 使代码更容易推理
- 编译器可以更好地优化代码
可变变量
当我们确实需要一个可变的值时,可以通过在变量名前添加mut
关键字来实现:
rust
fn main() {
let mut x = 5;
println!("The value of x is: {}", x);
x = 6; // 正确!x是可变的
println!("The value of x is: {}", x);
}
输出:
csharp
The value of x is: 5
The value of x is: 6
使用mut
可以清晰地向代码的未来读者表明,代码的其他部分将会改变这个变量的值。
常量
Rust中的常量(constant)与不可变变量有些相似,但有几个重要区别:
- 常量使用
const
关键字声明,而不是let
- 常量必须注明类型
- 常量可以在任何作用域中声明,包括全局作用域
- 常量只能设置为常量表达式,不能是函数调用的结果或运行时计算的值
rust
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
常量在程序运行的整个过程中都有效,适用于程序多个部分需要知道的值。
常量的命名约定是全部字母大写,并使用下划线分隔单词。
变量遮蔽(Shadowing)
Rust允许声明与之前变量同名的新变量,这称为变量遮蔽(shadowing):
rust
fn main() {
let x = 5;
let x = x + 1; // 新的x遮蔽了旧的x
{
let x = x * 2; // 在这个作用域内,又一个新的x遮蔽了外部的x
println!("The value of x in the inner scope is: {}", x); // 输出12
}
println!("The value of x is: {}", x); // 输出6
}
变量遮蔽与使用mut
的区别:
- 使用遮蔽时,我们实际上是创建了一个新变量,可以改变值的类型,但保持相同的名称
- 使用
mut
时,我们不能改变变量的类型
例如,以下代码是合法的:
rust
let spaces = " ";
let spaces = spaces.len(); // spaces从字符串类型变为数字类型
但这段代码会产生编译错误:
rust
let mut spaces = " ";
spaces = spaces.len(); // 错误:类型不匹配
错误信息:
ini
error[E0308]: mismatched types
--> src/main.rs:3:14
|
2 | let mut spaces = " ";
| ----- expected due to this value
3 | spaces = spaces.len();
| ^^^^^^^^^^^^ expected `&str`, found `usize`
总结
- Rust变量默认是不可变的,这有助于编写安全的代码
- 使用
mut
关键字可以创建可变变量 - 常量使用
const
关键字声明,必须注明类型,且只能设置为编译时可计算的值 - 变量遮蔽允许我们重用变量名,甚至可以改变值的类型
- 不可变性和变量遮蔽是Rust语言设计的重要特性,有助于减少bug并提高代码可读性