常量
常量
不允许改变值的变量,可能会使你想起另一个大部分编程语言都有的概念:常量(constants)。类似于不可变变量,常量是绑定到一个名称的不允许改变的值,不过常量与变量还是有一些区别。
首先,不允许对常量使用 mut。常量不光默认不能变,它总是不能变。声明常量使用 const 关键字而不是 let,并且必须注明值的类型。常量可以在任何作用域中声明,包括全局作用域,这在一个值需要被很多部分的代码用到时很有用。最后一个区别是,常量只能被设置为常量表达式,而不能是函数调用的结果,或任何其他只能在运行时计算出的值。
这是一个声明常量的例子,它的名称是 MAX_POINTS,值是 100,000。(Rust 常量的命名规范是使用下划线分隔的大写字母单词,并且可以在数字字面值中插入下划线来提升可读性):
const MAX_POINTS: u32 = 100_000;
在声明它的作用域之中,常量在整个程序生命周期中都有效,这使得常量可以作为多处代码使用的全局范围的值,例如一个游戏中所有玩家可以获取的最高分或者光速。将遍布于应用程序中的硬编码值声明为常量,能帮助后来的代码维护人员了解值的意图。如果将来需要修改硬编码值,也只需修改汇聚于一处的硬编码值。
const 与 static 对比
有两种不使用 let 声明的类型:const 和 static。另外,您需要为它们编写类型。这些是用于不变的变量(const 表示常量)。区别在于:
- const 是一个不变的值;
- static 是一个不变的值,并且具有固定的存储位置。
因此它们几乎相同。Rust 程序员几乎总是使用 const。您可以使用 ALL CAPITAL LETTERS(大写字母)来编写它们,并且通常在 main 函数之外。
const NUMBER_OF_MONTHS: u32 = 12;
const SEASONS: [&str; 4] = ["Spring", "Summer", "Fall", "Winter"];
这里对于不可变需要进行阐述,在 Rust 中默认使用 let 声明的绑定即不可变绑定,不可变绑定与 const 常量是完全不同的两种概念;首先,“不可变”准确地应该称为“不可变绑定”,是用来约束绑定行为的,“不可变绑定”后不能通过原“所有者”更改资源内容。例如:
let a = vec![1, 2, 3]; //不可变绑定, a <=> 内存区域A(1,2,3)
let mut a = a; //可变绑定,a <=> 内存区域A(1,2,3), 注意此a已非上句a,只是名字一样而已
a.push(4);
println!("{:?}", a); //打印:[1, 2, 3, 4]
“可变绑定”后,目标内存还是同一块,只不过,可以通过新绑定的 a 去修改这片内存了。
let mut a: &str = "abc"; //可变绑定, a <=> 内存区域A("abc")
a = "xyz"; //绑定到另一内存区域, a <=> 内存区域B("xyz")
println!("{:?}", a); //打印:"xyz"
上面这种情况不要混淆了,a = "xyz"
表示 a
绑定目标资源发生了变化。其实,Rust 中也有 const 常量,常量不存在“绑定”之说,和其他语言的常量含义相同:
const PI:f32 = 3.14;
可变性的目的就是严格区分绑定的可变性,以便编译器可以更好的优化,也提高了内存安全性。