我正在学习Rust,并且没有线程经验。我正在上Rustlings课程,并且已经解决了threads1.rs
练习,但是我不明白为什么我的Mutex
结构不需要取消引用。
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
struct JobStatus {
jobs_completed: u32,
}
fn main() {
let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let status_shared = Arc::clone(&status);
thread::spawn(move || {
for _ in 0..10 {
thread::sleep(Duration::from_millis(250));
let mut status_shared = status_shared.lock().unwrap();
status_shared.jobs_completed += 1; // why not *status_shared?
}
});
let mut jobs_completed: u32;
loop {
jobs_completed = status.lock().unwrap().jobs_completed;
if jobs_completed < 10 {
println!("waiting... ({} jobs done)", jobs_completed);
thread::sleep(Duration::from_millis(500));
} else {
break;
}
}
}
根据《书》的Chapter 16.3,我本来需要分配给
*status_shared.jobs_completed
为了获取到jobs_completed
字段,但这会产生错误:
error[E0614]: type `u32` cannot be dereferenced
--> src/main.rs:16:13
|
16 | *status_shared.jobs_completed += 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
这本书有一个指向简单类型的指针和上面的代码提供了对结构的引用的区别吗?
答案 0 :(得分:3)
status_shared
的类型为MutexGuard
。 MutexGuard
实现了DerefMut和Deref特质,并具有T
(在Mutex中存储的类型-在您的情况下为JobStatus
)中的deref目标。 / p>
当在对象后面的.
后面使用时,rust编译器将自动尝试将其重新引用为可以执行请求的操作的对象。因此,此处无需显式取消引用。 Deref chapter
答案 1 :(得分:1)
答案 2 :(得分:1)
与@ Matthias247 said一样,在.
之后自动取消引用
此外,由于操作符优先级,您尝试进行显式取消引用的尝试失败:*status_shared.jobs_completed
等效于*(status_shared.jobs_completed)
,因此它尝试取消引用u32
并失败,但是您想要{{1} }以便取消引用(*status_shared).jobs_completed
。