Richard Millen
Richard Millen

Reputation: 63

Borrow a vector inside a loop

I'm trying to update each element of a vector and then borrow the entire vector during each iteration, ex:

#![allow(unused)]

#[derive(Debug)]
pub struct Foo {
    value: i32,
}

fn main() {
    let mut foos: Vec<Foo> = vec![Foo { value: 1 }, Foo { value: 2 }, Foo { value: 3 }];

    for foo in &mut foos {
        update_single(foo);

        //save_all(&foos); <-- this doesn't compile - there's already a mutable borrow
    }
}

fn update_single(foo: &mut Foo) {
    println!("update_single");
    foo.value *= foo.value;
}

fn save_all(foos: &Vec<Foo>) {
    println!("save_all:");
    for foo in foos {
        println!("\t{:?}", foo);
    }
}

Note: I'm saving the updated vector as a blob e.g. via serde_json.

Upvotes: 3

Views: 1813

Answers (1)

Chai T. Rex
Chai T. Rex

Reputation: 3016

for foo in &mut foos will borrow the entirety of foos mutably throughout the entire for loop.

You can either borrow something mutably once or immutably any number of times, but not both. So, when you borrow the entire vector mutably for the duration of the loop, it can't be immutably borrowed again until you let go of that mutable borrow when the loop finishes.

You can get around this by borrowing each element mutably only on one line of the loop, rather than borrowing the entire vector for the entire loop.

    for i in 0..foos.len() {
        update_single(&mut foos[i]);
        save_all(&foos);
    }

Now we mutably get each item in the array, and it only mutably borrows each time on that one line.

Upvotes: 5

Related Questions