gpt4 book ai didi

rust - Mutex 可以引用结构但不能引用原语

转载 作者:行者123 更新时间:2023-11-29 08:04:41 27 4
gpt4 key购买 nike

以下代码中的结构 Counter 包装了 u32。我正在使用 Arc 来包装并使用 Mutex 来允许安全和共享地访问值。我省略了线程代码以提供一个简单的示例:

use std::sync::{Arc, Mutex};

fn main() {
#[derive(Debug)]
struct Counter {
count: u32,
}

let counter = Arc::new(Mutex::new(Counter { count: 0 }));

for _ in 0..10 {
let mut c_int = counter.lock().unwrap();
c_int.count += 1;
}

println!("{:?}", counter.lock().unwrap());
}

此处 counter.lock().unwrap() 能够透明地锁定互斥锁并解包结果,我不需要取消引用 Arc。对 c_int 的解引用也是透明的。

考虑以下代码,其中 Counter 替换为 u32:

use std::sync::{Arc, Mutex};

fn main() {
let counter = Arc::new(Mutex::new(32));

for _ in 0..10 {
let mut c_int = counter.lock().unwrap();
c_int += 1;
}

println!("{:?}", counter.lock().unwrap());
}

它不会编译,因为 c_int += 1 无效,因为它没有取消对 u32 的引用。

我的问题是:

  1. 为什么在通过像 Mutex 这样的智能指针使用时结构是特殊的而原语不是?

  2. 如何直接在 Arc 上使用 Mutex 的函数?

我认为两者都与 Deref 有关,但不确定如何。

最佳答案

c_int实际上不是整数或 Counter例如,它是一个 std::sync::MutexGuard<'_, T> .

为什么c_int.count += 1;的原因在第一个示例中工作的是 Deref强制转换:无论在哪里看到类似 foo.bar 的表达式,编译器检查是否 foo有成员(member)bar ,如果没有,则取消引用它,然后重试。在你的情况下,因为 c_int是互斥保护,它没有 count成员,编译器将尝试 (*c_int).count .

现在,std::sync::MutexGuard<'_, T>执行Deref<Target=T> ,在您的情况下,这意味着您可以获得 Counter离开互斥保护,编译器就停在那里。

但是,在整数情况下,您只有 c_int += 1 , 赋值本身不会触发 Deref强制,所以编译器理所当然地给你一个错误

8 |         (c_int) += 1;
| -------^^^^^
| |
| cannot use `+=` on type `std::sync::MutexGuard<'_, {integer}>`

要使第二个示例起作用,您必须取消引用自己:

*c_int += 1;

另见:

关于rust - Mutex 可以引用结构但不能引用原语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57443320/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com