常量

常量

不允许改变值的变量,可能会使你想起另一个大部分编程语言都有的概念:常量(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;

可变性的目的就是严格区分绑定的可变性,以便编译器可以更好的优化,也提高了内存安全性。

上一页
下一页