我有这段代码:
use std::sync::atomic::{AtomicUsize, Ordering};
const SOME_VAR: AtomicUsize = AtomicUsize::new(0);
fn main() {
println!("{}", SOME_VAR.load(Ordering::SeqCst));
println!("{}", SOME_VAR.fetch_add(10, Ordering::SeqCst));
println!("{}", SOME_VAR.load(Ordering::SeqCst));
}
这打印0 0 0
没有任何错误。在Java中,我可以使用final HashMap
并向其添加(k, v)
。在Rust中,我很惊讶编译器没有对我大喊大叫,但也没有增加我的原子值。我在这里做错了吗?
如果我使用static
:
static SOME_VAR: AtomicUsize = AtomicUsize::new(0);
我得到了结果0 0 10
。为什么它不适用于const
?
答案 0 :(得分:13)
保证static
变量具有单个实例,您可以对其进行引用。 const
变量没有此保证,并且允许编译器具有零个,一个或多个实例。
在您的情况下,代码相当于:
println!("{}", AtomicUsize::new(0).load(Ordering::SeqCst));
println!("{}", AtomicUsize::new(0).fetch_add(10, Ordering::SeqCst));
println!("{}", AtomicUsize::new(0).load(Ordering::SeqCst));
由于每个值都被创建并丢弃,因此不会从一个值传播到另一个值。
在某些方面,您可以将const
变量视为C或C ++ #define
- 从概念上讲,该值只是粘贴在任何地方使用。
Clippy 0.0.211 has a lint for this case:
error: a const item should never be interior mutable
--> src/main.rs:3:1
|
3 | const SOME_VAR: AtomicUsize = AtomicUsize::new(0);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| help: make this a static item: `static`
|
= note: #[deny(declare_interior_mutable_const)] on by default
= help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.211/index.html#declare_interior_mutable_const
error: a const item with interior mutability should not be borrowed
--> src/main.rs:6:20
|
6 | println!("{}", SOME_VAR.load(Ordering::SeqCst));
| ^^^^^^^^
|
= note: #[deny(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-nursery.github.io/rust-clippy/v0.0.211/index.html#borrow_interior_mutable_const
在Java中,我可以使用
final HashMap
是的,您可以非常轻松地在Java中创建非线程安全 HashMap
。 Rust并不想让创建可能导致内存不安全的代码变得容易。您需要保护具有适当安全性的类型,例如Mutex
,或者如果您的程序员保证只有全局值,您需要使用unsafe
代码永远被一个线程使用。
另见: