Упражнение с нитью Rustlings, почему я НЕ разыскиваю Mutex (Struct)? - PullRequest
0 голосов
/ 17 июня 2019

Я изучаю 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;
        }
    }
}

На основе Глава 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 ]

3 голосов
/ 17 июня 2019

status_shared относится к типу MutexGuard.MutexGuard реализует черты DerefMut и Deref , с целью разыменования T (тип, который хранится внутри Mutex - JobStatus в вашем случае.

Когда вы используете за . за объектом, компилятор ржавчины автоматически попытается разыскать его во что-то, где может быть выполнена запрошенная операция. Поэтому явное разыменование здесь не требуется. Это поведение описано в книге Rustв главе Разыменование

1 голос
/ 17 июня 2019

Как сказал @ Matthias247 , разыменование происходит автоматически после .

Кроме того, ваша попытка явного разыменования не удалась из-за приоритета оператора: *status_shared.jobs_completed эквивалентен *(status_shared.jobs_completed), поэтому он пытается разыменовать u32 и завершается неудачно, но вы хотите (*status_shared).jobs_completed для разыменования Arc<JobStatus>.

1 голос
/ 17 июня 2019

Arc<T> автоматически разыменовывается через черту Deref.

Ссылки:

...