Keyword static

source ·
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

可变的 statics 就像简单的 statics 一样,对它们也有一些限制。有关更多信息,请参见 Reference