在迭代时修改结构是否有优雅的解决方案?

Chr*_*ris 5 rust

我正在尝试构建迭代它们时更改的点向量:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

编译时,我收到错误:

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
Run Code Online (Sandbox Code Playgroud)

正如我在这里学到的,Rust不允许在迭代时修改结构,因此错误.

如何以优雅的方式修改它?如果我读到这个答案并且说得对,那么我想到了以下内容:

  1. 从向量中弹出项目,修改它并将其推回.
  2. 创建一个临时结构,我将更改的项目推送到并用循环外的临时结构替换原始结构(如何?).

虽然我认为我可以(1)工作,但我并不是真的很高兴所有这些流行音乐和推动(无论如何这是高性能吗?).关于(2),我不知道如何使它工作 - 如果这可行的话.

问题:

  1. 是(2)解决方案,如果是,它会是什么样子?
  2. 还有其他解决方案吗?
  3. 不同解决方案的优点或缺点是什么,特别是在性能方面?

小智 17

您无法修改迭代的结构,即向量points.但是,修改从迭代器获得的元素完全没有问题,您只需选择变为可变性:

for i in points.iter_mut() {
Run Code Online (Sandbox Code Playgroud)

或者,使用更现代的语法:

for i in &mut points {
Run Code Online (Sandbox Code Playgroud)

可变性是选择性的,因为迭代进行迭代会进一步限制迭代时可以执行的操作points.由于可变别名(即两个或两个以上指向相同的内存,其中至少有一个是&mut)是禁止的,你甚至无法读取pointsiter_mut()迭代器是各地.

  • 这些天你可以写'for in in&mut points`,因为它使用`IntoIterator`特性. (2认同)