 # For-loop moves a mutable vector borrow

Hi all,

I’m trying to understand the difference between these two ways of iterating over a mutably borrowed Vector of structs.

What I’m trying to accomplish:
I have an infinite loop, the first step of the loop iterates over all my Particle objects, and calls the `tick()` method on each one which modifies the Particle’s contents. I then do some math to figure out whether I’m done and `break` out of the infinite loop.

Question:
When I write the first part as `for particle in particles { particle.tick(); }` I get an error, saying that `particles` moved in the previous iteration of the loop, and cannot be used again. If I change it to iterate over `particles.iter_mut()` the error goes away.

I was under the impression that `for x in some_vec {...}` was just syntactic sugar for iterating over an iterator. Is my understanding correct, or am I missing something?

Code:

``````  // inside of Particle's impl block
fn tick(&mut self) {
let (p1,p2,p3) = self.p;
let (v1,v2,v3) = self.v;
let (a1,a2,a3) = self.a;
self.v = (v1+a1,v2+a2,v3+a3);
self.p = (p1+self.v.0, p2+self.v.1, p3+self.v.2)
}

// some function
fn nearest_particle_simulation(particles: &mut Vec<Particle>) -> usize {
let mut nearest = particles.id;
let mut nearest_streak = 0;
let streak_req = 1000;

loop {
for particle in particles {
particle.tick();
}

let this_nearest = nearest_to_origin(particles);

// new nearest, reset the streak
if nearest != this_nearest {
nearest = this_nearest;
nearest_streak = 0;
}
else {
nearest_streak += 1;
}

// streak has completed. we're done
if nearest_streak == streak_req {
break;
}
}

nearest
}

``````

This is a subtle difference between moving a mutable borrow (what’s happening in `for particle in particles` vs reborrowing, which is what’s happening in `for particle in particles.iter_mut()`). There was some recent discussion of this and @bluss gave a nice summary: What’s the difference between ‘for x in b’ and ‘for x in b.into_iter()’?.

1 Like