LaVOZs

The World’s Largest Online Community for Developers

'; Understanding &* to access a Rust Arc - LavOzs.Com

Reading about Condvar (condition variable for Rust) at https://doc.rust-lang.org/beta/std/sync/struct.Condvar.html I stumbled upon:

use std::sync::{Arc, Mutex, Condvar};
use std::thread;

let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = pair.clone();

// Inside of our lock, spawn a new thread, and then wait for it to start.
thread::spawn(move|| {
    let (lock, cvar) = &*pair2;
    let mut started = lock.lock().unwrap();
    *started = true;
    // We notify the condvar that the value has changed.
    cvar.notify_one();
});

// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
while !*started {
    started = cvar.wait(started).unwrap();
}

What is the &*pair2 thing? I think it has to do with being able to retrieve the pair from inside the Arc, but shouldn't it be better to have a simple method that retrives the internal object of the Arc as a reference?

Can somebody explain to me exactly what &* does?

The * operator turns the Arc<T> into T. The & operator borrows that T into &T.

So when we put them together, &*pair borrows the Arc<T> into &T.

Another way of writing that code would be:

let (lock, cvar) = pair2.deref();

Indeed, the original &*pair2 actually means &*pair2.deref() – the * forces the compiler to insert a .deref() call, and it's that method which performs the actual conversion.

Related
How do I print the type of a variable in Rust?
Why doesn't println! work in Rust unit tests?
How to disable unused code warnings in Rust?
How do I split a string in Rust?
Rust package with both a library and a binary?
Convert a String to int in Rust?
How can a Rust program access metadata from its Cargo package?
How do I implement a JavaScript-style callback?
Why are explicit lifetimes needed in Rust?
Why does the Rust compiler not optimize code assuming that two mutable references cannot alias?