Cannot Borrow Error
This page was last reviewed on Mar 27, 2022.
Dot Net Perls
Cannot borrow error. 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().
Error example. 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.
However We also try to borrow the Data mutably and add results to the vector in Data.
So The program fails to compile because we try to mutate (add results to) the same struct we are iterating over.
Info We could fix this program by not using 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
Fixed program. We can fix the error with the borrow checker by ensuring that the immutable borrow does not overlap with the mutable borrow.
Detail We separate out the values 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); }
A discussion. 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.
And This will allow the iter() to borrow immutably and not interfere with the mutable borrows elsewhere.
A summary. 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.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Mar 27, 2022 (new).
© 2007-2024 Sam Allen.