I have a struct that has 2 Vec
s. I want to be able to iterate over one while modifying the other one. Here's an example programme:
use std::slice;
struct S {
a: Vec<i32>,
b: Vec<i32>
}
impl S {
fn a_iter<'a>(&'a self) -> slice::Iter<i32> {
self.a.iter()
}
fn a_push(&mut self, val: i32) {
self.a.push(val);
}
fn b_push(&mut self, val: i32) {
self.b.push(val);
}
}
fn main() {
let mut s = S { a: Vec::new(), b: Vec::new() };
s.a_push(1);
s.a_push(2);
s.a_push(3);
for a_val in s.a_iter() {
s.b_push(a_val*2);
}
}
But there is this compiler error:
$ rustc iterexample.rs
iterexample.rs:28:9: 28:10 error: cannot borrow `s` as mutable because it is also borrowed as immutable
iterexample.rs:28 s.b_push(a_val*2);
^
note: in expansion of for loop expansion
iterexample.rs:26:5: 29:6 note: expansion site
iterexample.rs:26:18: 26:19 note: previous borrow of `s` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `s` until the borrow ends
iterexample.rs:26 for a_val in s.a_iter() {
^
note: in expansion of for loop expansion
iterexample.rs:26:5: 29:6 note: expansion site
iterexample.rs:29:6: 29:6 note: previous borrow ends here
iterexample.rs:26 for a_val in s.a_iter() {
iterexample.rs:27 println!("Looking at {}", a_val);
iterexample.rs:28 s.b_push(a_val*2);
iterexample.rs:29 }
^
note: in expansion of for loop expansion
iterexample.rs:26:5: 29:6 note: expansion site
error: aborting due to previous error
I understand what the compiler is complaining about. I have borrowed self
in the for loop, because I am still looping over it.
Conceptially there should be a way to do this though. I am only modifying s.b
, and not modifying the thing I'm looping over (s.a
). Is there anyway to write my programme to demostrate this separation, and allow this sort of programme to compile?
This is a simplified example of a larger programme, so I need to keep the general structure the same (a struct that has some things, one of which will be iterated over, and another that will be updated).