I don't quite get the idea of mutability in Rust in the following situation:
As far as I got it, if both are immutable (4) then it is just a read only vector. But as long as I make vector mutable, it doesn't matter if elements mutable or not...
With mutable vector I can always mutate elements even if I did not make them mutable...
let mut st1 = String::from("Some");
let mut st2 = String::from("Value");
let vec: Vec<&mut str> = vec![&mut st1, &mut st2];
Can someone explain in which situations above combinations should be used and if there are certain limits for each of them.
Thank you so much!
So first you need to understand, reference of reference
let mut i: i32 = 0;
{
let mut r: &i32 = &i;
*r += 1; //cannot assign to `*r`, which is behind a `&` reference
let rr: &&i32 = &r;
**rr += 1; // cannot assign to `**rr`, which is behind a `&` reference
let mr: &mut &i32 = &mut r;
**mr += 1; //cannot assign to `**mr`, which is behind a `&` reference
}
let mut m: &mut i32 = &mut i;
*m += 1; // OK
let rm: &&mut i32 = &m;
**rm += 1; // cannot assign to `**rm`, which is behind a `&` reference
let mm: &mut &mut i32 = &mut m;
**mm += 1; // OK
That mean that if you want to mutate a value behind two degrees of reference, you'll need both degrees to be a mutable reference.
Vec
fn main() {
let mut a: i32 = 0;
let mut b: i32 = 0;
// Immutable Vec with Immutable reference element
{
let v = vec![&a, &b];
let _ = v.pop(); // cannot borrow as mutable
*v[0] += 1; // cannot assign to data in an index of `Vec<&i32>`
}
// Mutable Vec with Immutable reference element
{
let mut v = vec![&a, &b];
let _ = v.pop(); // you can mutate the vec itself
*v[0] += 1; // but not the elements it referenced
// ^^^^^^^
// since, this is basically this
// vvvvvvv
let r: &mut &i32 = v.get_mut(0).unwrap();
**r += 1;
// cannot assign to `**r`, which is behind a `&` reference
}
// Immutable Vec with Mutable reference element
{
let v = vec![&mut a, &mut b];
let _ = v.pop();
*v[0] += 1;
let r: &mut &mut i32 = v.get_mut(0).unwrap();
// ^ cannot mutate immutable variable `v`
// since v is immutable, you cannot mutably borrow v
**r += 1;
}
// Mutable Vec with Mutable reference element
{
let mut v = vec![&mut a, &mut b];
let _ = v.pop();
*v[0] += 1;
let r: &&mut i32 = v.get(0).unwrap();
**r += 1;
// cannot assign to `**r`, which is behind a `&` reference
let r: &mut &mut i32 = v.get_mut(0).unwrap();
**r += 1;
}
}