I have an array of Element
s and I want to iterate over it to do some stuff, then iterate over all Element
s inside the loop to do something. There is a relation between elements so I want to iterate to all other elements to check something. The elements are mutable references for reasons. It's a bit broad, but I'm trying to be general (maybe I should not).
struct Element;
impl Element {
fn doSomething(&self, e: &Element) {}
}
fn main() {
let mut elements = [Element, Element, Element, Element];
for e in &mut elements {
// Do stuff...
for f in &mut elements {
e.doSomething(f);
}
}
}
As expected, I got this error:
cannot borrow
elements
as mutable more than once at a time
I know it's a normal behavior in Rust, but what's the recommended way to avoid this error? Should I copy the elements first? Forget about loops and iterate in a different way? Learn about code design?
Is there a Rusty way to do this?
DISCLAIMER: I know this is a common mistake and it may be answered elsewhere, but once again I'm lost. I did not find a relevant answer, maybe I don't know how to search. Sorry if it's a duplicate.
You cannot do this, period. The rules of references state, emphasis mine:
On the very first iteration, you are trying to get two mutable references to the first element in the array. This must be disallowed.
Your method doesn't require mutable references at all (
fn doSomething(&self, e: &Element) {}
), so the simplest thing is to just switch to immutable iterators:If you truly do need to perform mutation inside the loop, you will also need to switch to interior mutability. This shifts the enforcement of the rules from compile time to run time, so you will now get a panic if you try to get two mutable references to the same item at the same time.
You can use indexed iteration instead of iterating with iterators. Then, inside the inner loop, you can use
split_at_mut
to obtain two mutable references into the same slice.