I have this piece of code below where I iterate over a Vec
(self.regions
), and under the right conditions, I mutate the current element of the Vec
However, when processing a region
, I must also call another method on self
that borrows it, causing me to have both a mutable and shared reference of self
at the same time, which is obviously impossible (and will not compile)
How can I change my code in order to make it work ?
I've thought of moving line 3 outside the loop and using a iter()
instead of an iter_mut()
, but then I don't see how to "keep the two iterators in sync" in order to make sure that both pieces of code refer to the same region
fn growth(&'a mut self) {
for region in self.regions.iter_mut() {
let candidates = self.neighbors(region); // Has to involve taking a &self
// Do stuff with `candidates` that involves mutating `region`
}
}
Edit
My post was lacking context, so here is the full function. self.regions
is of type Vec<Vec<&'a Cell>>
, and the signature of neighbors
is fn neighbors(&self, region: &Vec<&Cell>) -> HashSet<&Cell>
.
The objective of my program is to tesselate a grid into random polyominoes, by randomly selecting some sources and (the part that I posted) "growing them" into regions by iterating over each region and adding a random neighbor of the region to the region itself.
The neighbors
function depends of the previous iterations' outcome, so it cannot be precomputed
fn growth(&'a mut self) -> bool {
let mut unchoosen_cells = 20; // More complex in reality
let mut steps: usize = 0;
while unchoosen_cells != 0 {
if steps > GROWTH_STEP_LIMIT { return false; }
for region in self.regions.iter_mut() {
if rand::random() { continue; }
let candidates = self.neighbors(region);
if let Some(cell) = candidates.iter().choose(&mut thread_rng()) {
// cell.in_region = true;
region.push(cell);
unchoosen_cells -= 1;
}
steps += 1;
}
}
true
}