Rust 为什么常量原子变量不更新,而静态原子变量更新?

Rust 为什么常量原子变量不更新,而静态原子变量更新?,rust,Rust,我有以下代码: 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!("

我有以下代码:

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
,没有任何错误。在Java中,我可以使用
最终HashMap
并向其添加
(k,v)
。在Rust中,我很惊讶编译器没有对我大喊大叫,但也没有增加我的原子值。我做错什么了吗

如果我使用
静态

static SOME_VAR: AtomicUsize = AtomicUsize::new(0);

我得到结果
010
。为什么它不能与
const
一起工作?

一个
静态
变量保证只有一个实例,您可以引用它。
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++ >代码>定义< /C> >概念上,无论使用什么地方,值都粘贴在上面。 :

错误:常量项不应是内部可变的
-->src/main.rs:3:1
|
3 | const SOME_VAR:AtomicUsize=AtomicUsize::new(0);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
|帮助:使其成为静态项:`static`
|
=注意:#[拒绝(声明内部可变常数)]默认打开
=帮助:有关更多信息,请访问https://rust-lang-nursery.github.io/rust-clippy/v0.0.211/index.html#declare_interior_mutable_const
错误:不应借用具有内部易变性的常量项
-->src/main.rs:6:20
|
6 | println!(“{}”,一些变量加载(排序::SeqCst));
|                    ^^^^^^^^
|
=注意:#[拒绝(借用内部可变常量)]默认打开
=帮助:将此常量分配给本地或静态变量,并在此处使用该变量
=帮助:有关更多信息,请访问https://rust-lang-nursery.github.io/rust-clippy/v0.0.211/index.html#borrow_interior_mutable_const
在Java中,我可以使用
final HashMap

是的,您可以在Java中非常轻松地创建非线程安全的HashMap。Rust不想让创建可能导致内存不安全的代码变得容易。您需要使用适当的安全性来保护类型,例如使用
互斥锁
,或者如果程序员保证一个全局值只能由一个线程使用,则需要使用
不安全的
代码

另见:


一个
静态
变量保证有一个实例,您可以引用它。
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++ >代码>定义< /C> >概念上,无论使用什么地方,值都粘贴在上面。 :

错误:常量项不应是内部可变的
-->src/main.rs:3:1
|
3 | const SOME_VAR:AtomicUsize=AtomicUsize::new(0);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
|帮助:使其成为静态项:`static`
|
=注意:#[拒绝(声明内部可变常数)]默认打开
=帮助:有关更多信息,请访问https://rust-lang-nursery.github.io/rust-clippy/v0.0.211/index.html#declare_interior_mutable_const
错误:不应借用具有内部易变性的常量项
-->src/main.rs:6:20
|
6 | println!(“{}”,一些变量加载(排序::SeqCst));
|                    ^^^^^^^^
|
=注意:#[拒绝(借用内部可变常量)]默认打开
=帮助:将此常量分配给本地或静态变量,并在此处使用该变量
=帮助:有关更多信息,请访问https://rust-lang-nursery.github.io/rust-clippy/v0.0.211/index.html#borrow_interior_mutable_const
在Java中,我可以使用
final HashMap

是的,您可以在Java中非常轻松地创建非线程安全的HashMap。Rust不想让创建可能导致内存不安全的代码变得容易。您需要使用适当的安全性来保护类型,例如使用
互斥锁
,或者如果程序员保证一个全局值只能由一个线程使用,则需要使用
不安全的
代码

另见:


Rust与Java的
final
没有任何相似之处,因为它不支持继承,并且默认情况下变量是不可变的。Java没有类似于Rust的
const
,因为Java倾向于依赖JVM来优化事情,而不是进行编译时评估。Rust的
const
更像C++的
constepr
,Java的
final
更像C++的
const
。清清楚楚!Rust没有任何类似于Java的
final
,因为它不支持继承,并且默认情况下变量是不可变的。Java没有类似于Rust的
const
,因为Java倾向于依赖JVM来优化事情,而不是进行编译时评估。Rust的
const
更像C++的
constepr
,Java的
final
更像C++的
const
。清清楚楚!