可变性
Rust 中的 constant 是不可变的。您既不能重新分配也不能修改它:
struct Foo(u32);
const FOO: Foo = Foo(5);
const mut FOO: Foo = Foo(5); // illegal
fn main() {
FOO = Foo(1); //illegal
FOO.0 = 2; //illegal
}
static 变量可以是可变的,因此可以修改或重新分配。请注意,编写/修改全局 static 变量是不安全的,因此需要 unsafe 块:
struct Foo(u32);
static FOO: Foo = Foo(5);
static mut FOO_MUT: Foo = Foo(3);
fn main() {
unsafe {
FOO = Foo(1); //illegal
FOO.0 = 2; //illegal
FOO_MUT = Foo(1);
FOO_MUT.0 = 2;
}
}
发生次数
当您编译二进制文件时,所有const“出现”(您在源代码中使用const)将直接替换为该值。
statics 将在您的二进制文件中有一个专门的部分用于放置它们(BSS 部分,请参阅Where are static variables stored in C and C++? 了解更多信息)。
总而言之,请尽可能使用const。当不可能时,因为您需要在程序中稍后使用非const 方法初始化变量,请使用lazy_static!。
内部可变性
虽然const 和static 都可以使用内部可变性,但您永远不应该使用 const。这是一个例子
use std::sync::atomic::{AtomicU32, Ordering};
static STATIC: AtomicU32 = AtomicU32::new(0);
const CONST: AtomicU32 = AtomicU32::new(0);
fn print() {
println!("static: {}", STATIC.load(Ordering::Relaxed));
println!("const: {}", CONST.load(Ordering::Relaxed));
}
fn main() {
STATIC.store(3, Ordering::Relaxed);
CONST.store(3, Ordering::Relaxed);
print();
}
这编译得很好,没有任何警告,但会导致不需要的行为。输出:
static: 3
const: 0
使用clippy时,会显示以下两个警告:
warning: a `const` item should never be interior mutable
--> src/main.rs:4:1
|
4 | const CONST: AtomicU32 = AtomicU32::new(0);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
|
= note: `#[warn(clippy::declare_interior_mutable_const)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const
warning: a `const` item with interior mutability should not be borrowed
--> src/main.rs:8:27
|
8 | println!("const: {}", CONST.load(Ordering::Relaxed));
| ^^^^^
|
= note: `#[warn(clippy::borrow_interior_mutable_const)]` on by default
= help: assign this const to a local or static variable, and use the variable here
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
warning: a `const` item with interior mutability should not be borrowed
--> src/main.rs:13:5
|
13 | CONST.store(3, Ordering::Relaxed);
| ^^^^^
|
= help: assign this const to a local or static variable, and use the variable here
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const