沙沙线练习,为什么不取消引用Mutex(Struct)?

时间:2019-06-17 02:13:17

标签: rust dereference

我正在学习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;
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

这本书有一个指向简单类型的指针和上面的代码提供了对结构的引用的区别吗?

3 个答案:

答案 0 :(得分:3)

status_shared的类型为MutexGuardMutexGuard实现了DerefMutDeref特质,并具有T(在Mutex中存储的类型-在您的情况下为JobStatus)中的deref目标。 / p>

当在对象后面的.后面使用时,rust编译器将自动尝试将其重新引用为可以执行请求的操作的对象。因此,此处无需显式取消引用。 Deref chapter

中的Rust书中对此行为进行了描述

答案 1 :(得分:1)

Arc<T>通过Deref特征自动取消引用。

参考文献:

答案 2 :(得分:1)

与@ Matthias247 said一样,在.之后自动取消引用

此外,由于操作符优先级,您尝试进行显式取消引用的尝试失败:*status_shared.jobs_completed等效于*(status_shared.jobs_completed),因此它尝试取消引用u32并失败,但是您想要{{1} }以便取消引用(*status_shared).jobs_completed