In the code below, calling a &mut self method while iterating a field of self will result in a immutable borrow and a mutable borrow. There will be two borrows and the compilation will fail.
#[derive(Default)]
struct Test {
list: Vec<Vec<i32>>,
cnt: Vec<i32>,
}
impl Test {
pub fn func1(&mut self) {
for i in self.list[0].iter() { // immutable borrow of *self
self.func2(*i); // mutable borrow of *self
}
}
pub fn func2(&mut self, i: i32) {}
}
fn main() {
let mut test = Test::default();
test.func1();
}
I can make a copy of the list vector and iterate over it, but is there a easier way to write this kind of code?
For the particular example, if you don't want to change the signatures and you don't need access to the list[0] during the call to func2, you could temporarily remove it from self:
pub fn func1(&mut self) {
let list0 = std::mem::take(&mut self.list[0]);
for i in &list0 {
self.func2(*i);
}
self.list[0] = list0;
}
Hello, I'm just learning myself, but I'll try to help solve this one. One question first: why does func2 need a &mut self? Will it modify one of the vectors? I'm asking to find out whether you're wanting to do something that is unsafe.
OK, if func2 only needs to access cnt (and not list) then what @quinedot suggested would work.
Another possibility is to separate the cnt and list in two different structs so that exclusive ownership of one does not require exclusive ownership of the other; however, that may be inconvenient.