I know in Rust, there can't be multiple reference to one object if one of them is mutable. So when I want to pass self
as a reference inside a loop that is borrowing a member already, it wouldn't compile.
I have a trait function that takes a reference to bar
:
trait Foo {
fn perform(&mut self, bar: &Bar);
}
In Bar
, I have a vector of Foo
s:
struct Bar {
foos: Vec<Box<dyn Foo>>,
}
The following code would not compile because it's borrowing self
twice
impl Bar {
fn do_it(&mut self) {
for foo in &mut self.foos {
foo.perform(self);
}
}
}
error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
--> src/lib.rs:12:25
|
11 | for foo in &mut self.foos {
| --------------
| |
| mutable borrow occurs here
| mutable borrow later used here
12 | foo.perform(self);
| ^^^^ immutable borrow occurs here
Is there nice way to do it so Foo::perform()
can use the references of both self
and bar
without the compiler complaining?
Edit
A couple ways i thought of to get around this:
- Use pointer
fn do_it(&mut self) {
let ptr = self as *const Bar;
for foo in &mut self.foos {
foo.perform(ptr);
}
}
- Take away from the vector then put it back after
fn do_it(&mut self) {
let len = self.foos.len();
for i in 0..len {
let foo = self.foos.swap_remove(i);
foo.perform(self);
self.foos.push(foo);
self.foos.swap(i, len-1);
}
}
Both ways are not rusty, though. I'm still looking for a way to make perform()
get the fields from Bar without taking its reference.