2 votes

Exercice sur les fils de rouille, pourquoi ne pas déréférencer Mutex(Struct) ?

Je suis en train d'apprendre Rust et je n'ai aucune expérience avec les threads. Je suis le cours Rustlings et j'ai résolu le problème du threads1.rs mais je ne comprends pas pourquoi ma Mutex n'a pas besoin d'être déréférencée.

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

Sur la base de Chapitre 16.3 du Livre, je me serais attendue à devoir assigner à des

*status_shared.jobs_completed

afin de obtenir à la jobs_completed mais cela génère une erreur :

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

La différence réside-t-elle dans le fait que le livre donne un pointeur sur un type simple et que le code ci-dessus donne une référence à une structure ?

5voto

Matthias247 Points 5447

status_shared est du type MutexGuard . MutexGuard met en œuvre le DerefMut y Deref avec une cible deref de T (le type qui est stocké à l'intérieur du Mutex - JobStatus dans votre cas.

Lorsque vous utilisez derrière un . derrière un objet, le compilateur Rust essaiera automatiquement de le déréférencer en quelque chose où l'opération demandée peut être effectuée. Le déréférencement explicite n'est donc pas nécessaire ici. Ce comportement est décrit dans le livre Rust dans la section Chapitre Deref

1voto

zerkms Points 105994

Arc<T> est automatiquement déréférencée par l'intermédiaire de l'élément Deref trait.

Références :

1voto

Jmb Points 2057

Comme @Matthias247 dit le déréférencement est automatique lorsque l'on se trouve derrière un .

En outre, votre tentative de déréférencement explicite échoue en raison de la préséance des opérateurs : *status_shared.jobs_completed est équivalent à *(status_shared.jobs_completed) Il tente donc de déréférencer un u32 et échoue, mais vous voulez (*status_shared).jobs_completed afin de déréférencer le Arc<JobStatus> .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X