以下代码中结构体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());
}
Run Code Online (Sandbox Code Playgroud)
这里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());
}
Run Code Online (Sandbox Code Playgroud)
它不会编译,因为c_int += 1它无效,因为它不会取消对 u32 的引用。
我的问题是:
为什么结构是特殊的,而基元不是通过智能指针使用的Mutex?
如何Mutex直接在Arc?
我认为两者都有关系,Deref但不确定如何。
c_int实际上不是整数或Counter实例,它是一个std::sync::MutexGuard<'_, T>.
c_int.count += 1;在第一个示例中起作用的原因是Deref强制:无论在哪里看到诸如 的表达式foo.bar,编译器都会检查是否foo有成员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}>`
Run Code Online (Sandbox Code Playgroud)
要使第二个示例工作,您必须取消对自己的引用:
*c_int += 1;
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
166 次 |
| 最近记录: |