Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an elegant solution to modifying a structure while iterating?

Tags:

I'm trying to build a vector of points that are changed while iterating over them:

struct Point {
    x: i16,
    y: i16,
}

fn main() {
    let mut points: Vec<Point> = vec![];
    // unsure if point is mutable
    points.push(Point { x: 10, y: 10 });
    // thus trying it explicitly
    let mut p1 = Point { x: 20, y: 20 };
    points.push(p1);

    for i in points.iter() {
        println!("{}", i.x);
        i.x = i.x + 10;
    }
}

When compiling, I get the error:

error[E0594]: cannot assign to immutable field `i.x`
  --> src/main.rs:16:9
   |
16 |         i.x = i.x + 10;
   |         ^^^^^^^^^^^^^^ cannot mutably borrow immutable field

As I learned here, Rust doesn't allow modifying the structure while iterating over it, thus the error.

How do I modify it in an elegant way? If I read this answer and get it right then the following comes to my mind:

  1. pop the item from the vector, modify it and push it back.
  2. create a temporary structure where I push the changed items to and replace original structure with the temporary one outside the loop (how?).

While I think I can get (1) working, I'm not really happy about all this pop's and push's (is this high-performance anyhow?). Concerning (2), I have no idea how to get it working - if this would work at all.

Questions:

  1. Is (2) an solution and if yes, how would it look like?
  2. Are there any other solutions?
  3. What's the advantage or disadvantage of the different solutions, especially with respect to performance?