rustborrow

Rust double mut borrow in loops


Looking for a way to push in both Vec<Vec<>> and it's inner Vec<>. I do understand why it fails, but still struggle to find some graceful way to solve it.

fn example() {
    let mut vec: Vec<Vec<i32>> = vec![];
    vec.push(vec![]);
    for i in &mut vec {
        i.push(1);
        if vec.len() < 10 {
            vec.push(vec![]); // second mut borrow
        }
    }
}

Solution

  • The borrow checker won't allow you to iterate over a vector by reference and modify it during iteration. The reason for that is that modifying the vector can reallocate its storage, which would invalidate the references used for iteration. (And there is also the question of what it means to iterate over a changing vector, do you want to visit the elements added during iteration or just the elements that were present originally.)

    The easiest fix that allows you to do what you want is to just iterate the vector using an index:

    fn example() {
        let mut vec: Vec<Vec<i32>> = vec![];
        vec.push(vec![]);
        let mut ind = 0;
        while ind < vec.len() {
            let i = &mut vec[ind];
            i.push(1);
            if vec.len() < 10 {
                vec.push(vec![]);
            }
            ind += 1;
        }
    }