Rustlings thread exercise, why do I NOT dereference Mutex(Struct)?

六月ゝ 毕业季﹏ 提交于 2020-08-20 05:11:07

问题


I'm learning Rust and have no experience with threads. I'm going through the Rustlings course and I've solved the threads1.rs exercise, but I don't understand why my Mutex struct doesn't need to be dereferenced.

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;
        }
    }
}

Based on Chapter 16.3 of The Book, I would have expected to need to assign to

*status_shared.jobs_completed

in order to get to the jobs_completed field, but that generates the error:

error[E0614]: type `u32` cannot be dereferenced
  --> src/main.rs:16:13
   |
16 |             *status_shared.jobs_completed += 1;
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Is the difference that the book gives a pointer to a simple type and the above code gives a reference to a struct?


回答1:


status_shared is of type MutexGuard. MutexGuard implements the DerefMut and Deref traits, with a deref target of T (the type which is stored inside the Mutex - JobStatus in your case.

When you use behind a . behind an object the rust compiler will automatically try to deref it into something where the requested operation can be performed. Therefore the explicit dereferencing is not necessary here. This behavior is described in the Rust book in the Deref chapter




回答2:


Arc<T> automatically dereferences via the Deref trait.

References:

  • https://doc.rust-lang.org/std/sync/struct.Arc.html#deref-behavior



回答3:


As @Matthias247 said, dereferencing is automatic when behind a .

Additionally, your attempt at explicit dereference fails because of operator precedence: *status_shared.jobs_completed is equivalent to *(status_shared.jobs_completed) so it attempts to dereference an u32 and fails, but you want (*status_shared).jobs_completed in order to dereference the Arc<JobStatus>.



来源:https://stackoverflow.com/questions/56624004/rustlings-thread-exercise-why-do-i-not-dereference-mutexstruct

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!