rustreference-counting

What is the canonical way to read a value inside an Arc?


There is probably no way this is the first time someone has asked this question, but for the life of me I couldn't find this answer. So I want to ask this in the hope that someone will either harshly chastise me and tell me where to actually go, or that lots of people will find this also useful :)

In a code example, I would say something like:

let a = Arc::new(37);
let a_clone = Arc::clone();
if a_clone.read().unwrap() == 37 { // this is the code I am not sure about
    println!("Hooray!");
} else {
    println!("when the heckity did that change")
}

Also, do I always need to clone before I read? Probably not, right? I also wouldn't mind a further explanation of the Arcs so I can understand what is actually going on without just mashing things in my IDE :)


Solution

  • If you have an Arc then you already have a strong reference, so cloning is not necessary. You only need to clone when you need to retain access to the value but also want to give a handle to the same value to something else, typically another thread or async task. (If the value doesn't need to be written to (in which case you also need interior mutability) and is cheaply copied, then you don't need Arc at all.)

    Arc<T> auto-derefs to T, so in the above code you can just say if *a == 37, for example. Because it auto-derefs, you can also call methods on the contained T directly on the Arc (so long as Arc doesn't also have a method with the same name, which is also why many members of Arc are associated functions and not methods).