What is different between &mut self and mut self?

struct Human {
name: String,
age: i8,
current_thought: String
}

fn with_thought(&mut self, thought: &str ) -> Human {
self.current_thought = thought.to_string();
return self
}

fn with_thought(mut self, thought: &str ) -> Human {
self.current_thought = thought.to_string();
return self
}

&mut self means that the method takes an argument of type &mut Human, which is a mutable reference. If you have some human and call human.with_thought(...), the human is potentially mutated but you can still use it after the call. Well, that's true provided that your method - as implemented - even compiles which it probably won't, because you can't use return self to return a Human. That's because &mut self is a shorthand for self: & mut Self which stands for self: &mut Human. So the variable self inside of the method body has the wrong type of you want to return a Human. It's not a human value, it's just a mutable reference to a human value you don't own. OTOH, since the mutation is visible to the caller, you probably don't need to return anything anyways. But the method name suggests some kind of builder style method: taking self (or mut self) and returning self at the end can allow for easier changing of theme method calls.

mut self is pretty much the same as self, the type of the argument is Human, so the argument is moved into the function call, ownership is transferred. Calling human.with_thought(...) gives away the human. You can't use it after the call anymore (but you can use the return value of that call if you assign it to a variable). In the method definition

fn foo(mut self) {
    // use self 
}

is the same as

fn foo(self) {
    let mut this = self;
    // use this
}

The mut means that the local variable inside of the method body that holds the argument is mutable. Unlike with mutable references (i. e. unlike the case with &mut self), this doesn't allow mutating anything outside of the scope of the method call though. As the second code example above demonstrates, even a value in an immutable variable can later be moved out of that variable into a mutable one and then be mutated (which is what the let mut this = self does).

3 Likes

Please, read

1 Like

I got it, thank you