我有这个密码:

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

推荐答案

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制作non-thread-safe HashMap.Rust不想让创建可能导致内存不安全的代码变得容易.您需要使用适当的安全性来保护类型,比如Mutex,或者如果you the programmer保证一个全局值只能由一个线程使用,则需要使用unsafe代码.

另见:

Rust相关问答推荐

将JSON密钥转换为Polars DataFrame

是否可以为`T:Copy`执行`T. clone`的测试

将内部类型作为参数的泛型 struct 上的方法

如何将像烫手山芋一样不透明的值从一个Enum构造函数移动到下一个构造函数?

使用Box优化可选的已知长度数组的内存分配

在铁 rust 中传递所有权

带参考文献的 rust 元组解构

在IntoIter上调用.by_ref().Take().rev()时会发生什么情况

根据填充系数以相对大小在给定空间中布局项目

Rust移动/复制涉及实际复制时进行检测

Const 上下文:从 init 函数创建具有 const 通用长度的数组

如何在 `connect_activate()` 之外创建一个 `glib::MainContext::channel()` 并将其传入?

需要哪些编译器优化来优化此递归调用?

trait 对象指针的生命周期

如何在 Rust 中按 char 对字符串向量进行排序?

在 Rust 中实现资源消耗的安全包装器

为什么我不能克隆可克隆构造函数的Vec?

在 Rust 中如何将值推送到枚举 struct 内的 vec?

编写 TOML 文件以反序列化为 struct 中的枚举

如何将 u8 切片复制到 u32 切片中?