🎯前言
变量默认是不可改变的(immutable)。这是 Rust 提供给你的众多优势之一,让你得以充分利用 Rust 提供的安全性和简单并发性来编写代码。不过,你仍然可以使用可变变量。让我们探讨一下 Rust 为何及如何鼓励你利用不可变性,以及何时你会选择不使用不可变性。
🎯变量
Rust 编译器保证,如果声明一个值不会变,它就真的不会变,所以你不必自己跟踪它。这意味着你的代码更易于推导。
不过可变性也是非常有用的,可以用来更方便地编写代码。尽管变量默认是不可变的,你仍然可以在变量名前添加
mut
来使其可变,mut
也向读者表明了其他代码将会改变这个变量值的意图。
🎯常量
- 常量 (constants) 是绑定到一个名称的不允许改变的值,不过常量与变量还是有一些区别:
— 首先,不允许对常量使用
mut
。常量不光默认不可变,它总是不可变。声明常量使用const
关键字而不是let
,并且 必须 注明值的类型。— 常量可以在任何作用域中声明,包括全局作用域,这在一个值需要被很多部分的代码用到时很有用。
— 最后一个区别是,常量只能被设置为常量表达式,而不可以是其他任何只能在运行时计算出的值。
- 在程序运行期间,常量在其声明的作用域内一直有效。
- 命名规范:Rust里常量使用全大写字母,每个单词之间用下划线分开,例如:
- —MAX_POINTS
提醒:可以在数字里面可以加入下划线,增加可读性,如:const MAX:u32=100_100.
🎯Shadowing(隐藏)
我们可以定义一个与之前变量同名的新变量。Rustacean 们称之为第一个变量被第二个 隐藏(Shadowing) 了,这意味着当您使用变量的名称时,编译器将看到第二个变量。实际上,第二个变量“遮蔽”了第一个变量,此时任何使用该变量名的行为中都会视为是在使用第二个变量,直到第二个变量自己也被隐藏或第二个变量的作用域结束。可以用相同变量名称来隐藏一个变量,以及重复使用
let
关键字来多次隐藏。
fn main() { let x = 5; let x = x + 1; { let x = x * 2; println!("The value of x in the inner scope is: {x}"); } println!("The value of x is: {x}"); }
分析:这个程序首先将 x 绑定到值 5 上。接着通过 let x = 创建了一个新变量 x,获取初始值并加 1,这样 x 的值就变成 6 了。然后,在使用花括号创建的内部作用域内,第三个 let 语句也隐藏了 x 并创建了一个新的变量,将之前的值乘以 2,x 得到的值是 12。当该作用域结束时,内部 shadowing 的作用域也结束了,x 又返回到 6。
隐藏与将变量标记为 mut 是有区别的:
- 当不小心尝试对变量重新赋值时,如果没有使用 let 关键字,就会导致编译时错误。
- 通过使用 let,我们可以用这个值进行一些计算,不过计算完之后变量仍然是不可变的。
- 当再次使用 let 时,实际上创建了一个新变量,我们可以改变值的类型,并且复用这个名字。
let spaces = " "; let spaces = spaces.len();
第一个
spaces
变量是字符串类型,第二个spaces
变量是数字类型。隐藏使我们不必使用不同的名字,如spaces_str
和spaces_num
;相反,我们可以复用spaces
这个更简单的名字。然而,如果尝试使用mut
,将会得到一个编译时错误,如下所示:
let mut spaces = " "; spaces = spaces.len();
类型不匹配。