rust borrow check looks very smart , it can check and flat reads and writes of loop. but how can I bypass it?
Following code works well:
fn main() {
let mut lines = [
vec![1, 2, 3],
vec![4, 5, 6],
vec![7, 8, 9],
];
for i in 0 .. lines.len() {
let line = &lines[i];
for item in line {
// if found odd number, push zero!
if item % 2 == 1 {
lines[i].push(0);
break; // works fine! if comment it, will error!
}
}
}
dbg!(lines);
}
When comment the "break" line, will got:
error[E0502]: cannot borrow `lines[_]` as mutable because it is also borrowed as immutable
--> src/main.rs:13:17
|
10 | let line = &lines[i];
| --------- immutable borrow occurs here
11 | for &item in line {
| ---- immutable borrow later used here
12 | if item == 5 {
13 | lines[1].push(55);
| ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
error: aborting due to previous error
You don't bypass the borrow checker. You consider what it tells you and reconsider your program to match.
Here it tells you that you can't modify something you're currently iterating on (r^w principle), so don't do that. If you want to add as many zeroes as there are odd number in each line, do that: count the number of odds in the line, then add that many zeroes:
use std::iter::repeat;
fn main() {
let mut lines = [
vec![1, 2, 3],
vec![4, 5, 6],
vec![7, 8, 9],
];
for line in lines.iter_mut() {
let odds = line.iter().filter(|it| *it % 2 == 0).count();
line.extend(repeat(0).take(odds));
}
dbg!(lines);
}