Modifying the contents of an array of Vectors in Rust

Rust  can be very particular when it comes to mutability and references, and it is often not clear what is wrong.  Take this example:


let test = {
  vec![1u,2],
  vec![3u,4],
};
test[0][0] = 5;

As you might expect, this fails with an error message about mutability (since variables are immutable by default).

error: cannot borrow immutable vec content 'test[..]' as mutable
test[0][0] = 5;
^^^^^^^

This is an easy fix – we just need to make test mutable:


let mut test = {
  vec![1u,2],
  vec![3u,4],
};
test[0][0] = 5;

Once again, all is well – but what if we want to borrow each row individually to make operations a little more clear?


let test = {
  vec![1u,2],
  vec![3u,4],
};
let mut row = &test[0];
row[0] = 6;

Notice that test is no longer mutable (we aren’t actually modifying test). Instead, we create a new mutable variable row that is a reference to the array element we want. Unfortunately this takes us right back to a mutability error. This time, we can’t assign to the immutable content:

error: cannot assign to immutable vec content
row[0] = 5;
^^^^^^

So it turns out that making row mutable simply allows us to change the value of row. To change the contents of row we need to make the contents mutable. To do that, we need a mutable reference: &mut.


let test = {
  vec![1u,2],
  vec![3u,4],
};
let row = &mut test[0];
row[0] = 6;

Now we are grabbing a mutable reference which will let us change the contents of row, but if you compile, there is still another problem:

error: cannot borrow immutable vec content 'test[..]' as mutable
let row = &mut test[0];
               ^^^^^^

If you’ve read this far, you should recognize the original error about test being immutable. It turns out that in order to borrow a mutable element of an array, the array must also be mutable. It makes sense – despite not altering the variable test, we are altering the contents. Taking this into account we can finally get some working code:


let mut test = {
  vec![1u,2],
  vec![3u,4],
};
let row = &mut test[0];
row[0] = 6;

Perhaps not the most obvious way to modify contents of an array of vectors, but it does make a certain sense once you wrap your mind around it.