Expand description
静态项是在程序的整个持续时间内有效的值 ('static
生命周期)。
从表面上看,static
项与 const
非常相似:两者都包含一个值,都需要类型注解,并且都只能使用常量函数和值进行初始化。
但是,static
与众不同之处在于它们表示内存中的一个位置。
这意味着您可以引用 static
项,甚至可以对其进行修改,从而使它们本质上是变量。
静态项不会在程序结束时调用 drop
。
有两种类型的 static
项:与 mut
关键字关联声明的项和没有关联声明的项。
静态项不能移动:
ⓘ
static VEC: Vec<u32> = vec![];
fn move_vec(v: Vec<u32>) -> Vec<u32> {
v
}
// 该行导致错误
move_vec(VEC);
Run简单的 static
访问非 mut
static
项被认为是安全的,但也存在着一些限制。
最值得注意的是,static
值的类型需要实现 Sync
trait,排除了像 RefCell
这样的内部可变性容器。
有关更多信息,请参见 Reference。
static FOO: [i32; 5] = [1, 2, 3, 4, 5];
let r1 = &FOO as *const _;
let r2 = &FOO as *const _;
// 对于严格只读的静态,引用将具有相同的地址
assert_eq!(r1, r2);
// 在许多情况下,可以像使用变量一样使用静态项
println!("{FOO:?}");
Run可变的 static
如果使用 mut
关键字声明了一个 static
项,则允许程序对其进行修改。
但是,访问可变的 static
可能以多种方式导致未定义的行为,例如由于多线程上下文中的数据竞争。
因此,对可变的 static
的所有访问都需要一个 unsafe
块。
尽管它们不安全,但可变的 static
在许多情况下是必要的:
它们可以用来表示整个程序共享的全局状态,或者在 extern
块中绑定到 C 库中的变量。
在 extern
块中:
extern "C" {
static mut ERROR_MESSAGE: *mut std::os::raw::c_char;
}
Run可变的 static
s 就像简单的 static
s 一样,对它们也有一些限制。有关更多信息,请参见 Reference。