默认不可变状态
首先我们开始讲解变量状态,Rust变量状态表示变量所绑定的类型值是否可以修改。
Rust变量的状态有两种
- 默认不可变(immutable);
- 可变(mutable);
为什么 Rust 默认不可变变量?什么时候才会考虑使用可变变量。
首先,Rust 默认变量值不可变与确保内存安全、易于实现并发编程的目标有直接关系。
- 当变量值不可变时,意味着一旦值被绑定一个变量上,就不能改变值;
- 不可变变量可以被编译器优化提高程序的性能;
我们简单做演示:
使用 cargo new variables 命令在 projects 目录生成一个叫做 variables 的新项目,接着,在新建的 variables 目录,打开 src/main.rs 并将代码替换为如下代码,目前代码还不能编译:
文件名: src/main.rs
fn main() {
let x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
}
保存并使用 cargo run 运行程序。应该会看到错误信息如:
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
编译器已经帮助我们找出程序中的错误!
Rust开发很多时候就是和编译器斗争的过程。
这个过程绝对值得,因为编译器可以帮助我们提前发现代码中潜在错误。
Rust语言也被人们称为面向编译器的语言。
错误信息指出: 不能对不可变变量 x 二次赋值(cannot assign twice to immutable variable x)。
代码尝试改变不可变变量的值,编译时错误是很重要的,否则很可能导致难以跟踪发现的 bug。
Rust 编译器严格执行:如果声明一个值不会变,它就真的不会变。
当阅读和编写代码时,对于不可变变量,我们无需刻意追踪值会改变,这也使得代码易于阅读推导。
可变状态
Rust变量只是默认不可变;可变变量在开发中依然是需要的。
在变量名之前添加 mut 关键字、便可使变量绑定的值可变。
除了允许值可变之外,mut 关键字也向代码阅读者表明了后续代码可能会改变这个变量值。
例如,我们将 src/main.rs 代码做以下修改:
文件名:src/main.rs
fn main() {
let mut x = 5;//可变值变量
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
}
现在运行这个程序,出现如下内容:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs
Running `target/debug/variables`
The value of x is: 5
The value of x is: 6
mut关键字允许把绑定到 x 的值从 5 改成 6。
某些时候,为了让代码更容易编写,我们会考虑在代码中使用可变变量。
:bell:但这是一种交换:得到便捷的同时意味着失去,可变变量使得代码的跟踪难度大大增加。
如何衡量取舍?
除了防止出现 bug 外,到底是使用可变变量还是不可变变量,还需要我们权衡考虑以下方面:
使用大型数据结构时,采用可变变量,这样可能比借助值复制得到新实例性能更好;
对于较小的数据结构,采用不可变变量,执行值复制策略更可取,因为代码更易理解,为代码可读性牺牲一点性能是值得的。