collections - 如何在迭代集合的同时修改集合?

标签 collections iterator rust immutability

我有一个 Board (又名 &mut Vec<Vec<Cell>> )我想在迭代时更新它。我要更新的新值来自需要 &Vec<Vec<Cell>> 的函数到我正在更新的收藏。

我试过几种方法:

  1. 使用 board.iter_mut().enumerate()row.iter_mut().enumerate()这样我就可以更新 cell在最内层的循环中。 Rust 不允许调用 next_gen功能,因为它需要 &Vec<Vec<Cell>>当您已经有一个可变引用时,您不能再有一个不可变引用。

  2. 更改 next_gen接受 &mut Vec<Vec<Cell>> 的函数签名. Rust 不允许对一个对象进行多个可变引用。

我目前正在推迟对 HashMap 的所有更新然后在我执行迭代后应用它们:

fn step(board: &mut Board) {
    let mut cells_to_update: HashMap<(usize, usize), Cell> = HashMap::new();
    for (row_index, row) in board.iter().enumerate() {
        for (column_index, cell) in row.iter().enumerate() {
            let cell_next = next_gen((row_index, column_index), &board);
            if *cell != cell_next {
                cells_to_update.insert((row_index, column_index), cell_next);
            }
        }
    }

    println!("To Update: {:?}", cells_to_update);
    for ((row_index, column_index), cell) in cells_to_update {
        board[row_index][column_index] = cell;
    }
}

Full source

有没有办法让这段代码更新 board “就地”,也就是说,在最内层的循环内,同时仍然能够调用 next_gen在最内层循环中?

免责声明:

我正在学习 Rust,我知道这不是最好的方法。我正在玩耍,看看我能做什么,不能做什么。我也试图限制任何复制来限制我自己。作为oli_obk - ker mentions, this implementation for Conway's Game of Life is flawed .

此代码旨在衡量几件事:

  1. 如果可能的话
  2. 如果是惯用的 Rust

根据我在评论中收集到的信息,std::cell::Cell 是可能的.但是,使用 std:cell:Cell规避了一些核心 Rust 原则,我在最初的问题中将其描述为我的“困境”。

最佳答案

Is there a way that I could make this code update the board "in place"?

有一种类型专门用于此类情况。巧合的是std::cell::Cell .您可以更改 Cell 的内容,即使它已被多次借用。 Cell 仅限于实现 Copy 的类型(对于其他类型,您必须使用 RefCell ,如果涉及多个线程,则必须将 Arc 与类似于 Mutex 的东西)。

use std::cell::Cell;

fn main() {
    let board = vec![Cell::new(0), Cell::new(1), Cell::new(2)];

    for a in board.iter() {
        for b in board.iter() {
            a.set(a.get() + b.get());
        }
    }
    println!("{:?}", board);
}

关于collections - 如何在迭代集合的同时修改集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30966867/

相关文章:

java - 如何在 java 中从 ArrayList<Object[]> 创建 Object[][]

java - 确定要使用的 Java 集合类型

c++ - 递减迭代器直到 vector 的 .begin()

c++ - Comparator 可以用来设置新的 key ,不是吗?

Rust:无法将 Trait RangeBounds 制成对象

java - 如何使用自定义比较器比较两个数组列表是否相等?

c++ - STL vector 通过指针删除

rust - 包装类型时为 "no method found for type T in the current scope"

error-handling - 如何重用 `Result`?

php - sql垃圾收集与清理php中的查询