i read that in order to mutate date in a struct i have to use &mut self, so i was experimenting..
When i am using a Mutex to guard data in a struct, rust allows the data to be updated, can anyone explain the logic behind it?
use std::sync::Mutex;
#[derive(Debug)]
struct Actor {
name: Mutex<String>,
}
impl Actor {
fn update(&self) {
*self.name.lock().unwrap() = "new name".into();
}
}
fn main() {
let actor = Actor { name: Mutex::new("abcd".into()) };
actor.update();
dbg!(actor);
}
This is known as interior mutability. In reality &self means shared access and &mut self means unique access. In your case, mutation is safe even in the face of shared access due to the mutex. Check out this article:
@alice , @Cerber-Ursi if i understand correctly (plz correct me if i am wrong) &self only affects data that cannot be dereferenced ?? let's say exterior data, that is not hidden behind Type ??
I don't really understand what you mean, but interior mutability requires a Cell-like type to separate the immutable reference and the mutable data. Examples of Cell-like types include:
&self affects everything, but here you can get an owned (therefore mutable) MutexGuard by using &Mutex. That the whole point of such synchronization primitives, after all.
here my first impression (without knowing the CuteCatName definition) will be that &mut self is used to update the age, and let's assume get_mut() is named something else that does not indicate that its a mutable reference. because the return value is an immutable ref &str.
why &str can be modified, and is there a convention or something intuitive to quickly find out if its immutable or not without looking through the code base for the definition ??
It cannot. If you return &mut str, then it can, and that is indicated by the &mut. However, if you returned a &CuteCatName, then you are correct that there's nothing in the signature to indicate that its contents can be mutated. But if you have a &str then that is always immutable.
No, you don't have to have &mut self to mutate. The immutable/mutable reference distinction is a not-quite-accurate oversimplification. & is shared, and &mut is exclusive access.
You can mutate shared data, but such mutation needs extra care for thread safety. So &self can be entirely valid for mutation if you use a thread-safe construct with it. & does not guarantee immutability. It only allows itself to be shared.