目前为止全书都尽量避免讨论 全局变量(global variables),Rust 确实支持他们,不过这对于 Rust 的
所有权规则来说是有问题的。如果有两个线程访问相同的可变全局变量,则可能会造成数据竞争。
全局变量在 Rust 中被称为 静态(static)变量。示例 19-9 展示了一个拥有字符串 slice 值的静态变量的
声明和应用:
文件名: src∕main.rs
static HELLO_WORLD: &str = “Hello, world!”;
fn main() {
println!(“name is: {}”, HELLO_WORLD);
}
示例 19-9: 定义和使用一个不可变静态变量
静态(static)变量类似于第三章 ” 变量和常量的区别” 部分讨论的常量。通常静态变量的名称采用
SCREAMING_SNAKE_CASE 写法。静态变量只能储存拥有 ’ static 生命周期的引用,这意味着 Rust 编译
器可以自己计算出其生命周期而无需显式标注。访问不可变静态变量是安全的。
常量与不可变静态变量可能看起来很类似,不过一个微妙的区别是静态变量中的值有一个固定的内存地
址。使用这个值总是会访问相同的地址。另一方面,常量则允许在任何被用到的时候复制其数据。
常量与静态变量的另一个区别在于静态变量可以是可变的。访问和修改可变静态变量都是 不安全的。示
例 19-10 展示了如何声明、访问和修改名为 COUNTER 的可变静态变量:
文件名: src∕main.rs
static mut COUNTER: u32 = 0;
fn add_to_count(inc: u32) {
unsafe {
COUNTER += inc;
}
}
fn main() {
add_to_count(3);
unsafe {
println!(“COUNTER: {}”, COUNTER);
}
}
就像常规变量一样,我们使用 mut 关键来指定可变性。任何读写 COUNTER 的代码都必须位于 unsafe
块中。这段代码可以编译并如期打印出 COUNTER: 3,因为这是单线程的。拥有多个线程访问 COUNTER
则可能导致数据竞争。
拥有可以全局访问的可变数据,难以保证不存在数据竞争,这就是为何 Rust 认为可变静态变量是不安全
的。任何可能的情况,请优先使用第十六章讨论的并发技术和线程安全智能指针,这样编译器就能检测
不同线程间的数据访问是否是安全的。
Rust从入门到实战系列二百二十四:访问或修改可变静态变量
最新推荐文章于 2024-07-04 22:35:51 发布