Trying to learn Rust and got really confused with the solution from the move_semantics3.rs exercise.
Here is the exercise for reference:
// move_semantics3.rs
//
// Make me compile without adding new lines -- just changing existing lines! (no
// lines with multiple semicolons necessary!)
#[test]
fn main() {
let vec0 = vec![22, 44, 66];
let mut vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
vec.push(88);
vec
}
And the solution, as the compiler itself will tell you is just to add the mut keyword into the fill_ vec function like so
fn fill_vec(mut vec: Vec<i32>) -> Vec<i32>
However, I don’t get how you can get vec0, which is not defined as mutable and just pass it in as mutable in the function. Can you just magically transform an immutable vector into a mutable one by changing the function argument?
This is so confusing...
It's not the value that is mutable/not mutable, it's the binding.
Here,
vec0is declared not-mutable, so no mutable access to the value is possible through the bindingvec0(not accounting for interior mutability, which is beyond the scope of this question). When the value is passed tofill_vec()by means of the bindingvec0,fill_vecreceives either a copy of the value or the value itself (depending onCopy, again, beyond scope), and binds the value to a new variablevec. It is that bindingvecwhich itself is declaredmut, which allows for mutable access to the value behindvec.