In developing Rust programs, we may encounter a "cannot borrow as mutable" error when using an iterator. This can occur in a loop that calls iter()
.
In Rust, we must not modify data that we have borrowed for an iter
—this would cause the iterator to work incorrectly. To fix this error, we can separate the immutable data for the iter()
.
Consider this program—it won't compile because the borrow checker finds an error. We try to iterate with iter()
over part of the Data struct
.
struct
we are iterating over.iter()
at all, and using a for
-loop. Or we could change our data structures to avoid the problem.struct Data { values: Vec<u8>, results: Vec<bool> } fn add_result(data: &mut Data) { data.results.push(true); } fn main() { let mut data = Data { values: vec![1, 2, 3], results: vec![] }; for &v in data.values.iter() { if v == 1 { // Won't compile. add_result(&mut data); } } }error[E0502]: cannot borrow data as mutable because it is also borrowed as immutable
We can fix the error with the borrow checker by ensuring that the immutable borrow does not overlap with the mutable borrow.
Vector
to allow it to be borrowed immutably. The Data struct
can then be borrowed mutably with no problem.struct Data { results: Vec<bool> } fn add_result(data: &mut Data) { data.results.push(true); } fn main() { // Use separate variable for the data we iterate. let values = vec![1, 2, 3]; let mut data = Data { results: vec![] }; for &v in values.iter() { if v == 1 { add_result(&mut data); } } println!("{:?}", data.results); }[true]
When developing Rust we must consider how our data structures are used. For data that is iterated upon, we can separate this from other data.
iter()
to borrow immutably and not interfere with the mutable borrows elsewhere.The Rust borrow checker can be frustrating. But by ensuring that borrowed data is not messed up elsewhere in the program, we can be assured programs will work correctly.