const 和 static 几乎所有时候,如果你可以在两者之间选择,选择const。实际上你很少需要你的常量关联一个内存位置,而且使用const允许你不止在在自己的包装箱还可以在下游包装箱中使用像常数扩散这样的优化。
const
常量贯穿于整个程序的生命周期。更具体的,Rust 中的常量并没有固定的内存地址。这是因为实际上它们会被内联
到用到它们的地方。为此对同一常量的引用并不能保证引用到相同的内存地址。
常量的声明:
1 | const MAX : u32 = 999; |
常量与变量的区别:
- 常量必须、只能、且默认是不可变的,但变量可通过mut来声明为可变的
- 声明的语法不同,使用关键字const
- 常量声明时候必须指明类型,编译器不会进行自动推导
- 常量可以是一个表达式而不是一个值,这个表达式可能在运行时才能被计算出来
常量的命名规范:
- 全部使用大写
- 使用
_
来进行单词之间的分隔 - 可以使用
_
来代替数字表达中的,
,从而更便于代码阅读,例如数字100,000
可声明为常量如下:1
const MAX_BALANCE: u32 = 100_000;
常量的作用域:
- 常量可以在任何作用域来声明
- 常量在所声明的作用域内,是一直可用的
例如,在应用程序域声明常量,则在整个应用程序的所有代码中都可以使用,比如一个游戏程序中所设定的最大奖励金额
常量的必要性:
- 将程序中需要硬编码的值作为常量是有必要的
- 这样确保代码未来更容易维护
- 且确保了只需变更一处代码即可更新该值
static
Rust 以静态量的方式提供了类似“全局变量”的功能。它们与常量类似,不过静态量在使用时并不内联。这意味着对每一个值只有一个实例,并且位于内存中的固定位置。
1 | static N: i32 = 5; |
静态量贯穿于整个程序的生命周期,因此任何存储在常量中的引用有一个’static生命周期:
1 | static NAME: &'static str = "Steve"; |
可变性
可以用mut关键字引入可变性:
1 | static mut N: i32 = 5; |
因为这是可变的,一个线程可能在更新N同时另一个在读取它,导致内存不安全。因此访问和改变一个static mut是不安全(unsafe)
的,因此必须在unsafe块中操作:
1 | # static mut N: i32 = 5; |
初始化
const
和static
都要求赋予它们一个值。它们必须只能被赋予一个常量表达式的值。换句话说,你不能用一个函数调用的返回值或任何相似的复合值或在运行时赋值。
如果想赋予一个非常量表达式,可以参考用第三方库lazy_static。