我有一个 Board
(又名 &mut Vec<Vec<Cell>>
)我想在迭代时更新它。我要更新的新值来自需要 &Vec<Vec<Cell>>
的函数到我正在更新的收藏。
我试过几种方法:
使用
board.iter_mut().enumerate()
和row.iter_mut().enumerate()
这样我就可以更新cell
在最内层的循环中。 Rust 不允许调用next_gen
功能,因为它需要&Vec<Vec<Cell>>
当您已经有一个可变引用时,您不能再有一个不可变引用。更改
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;
}
}
有没有办法让这段代码更新 board
“就地”,也就是说,在最内层的循环内,同时仍然能够调用 next_gen
在最内层循环中?
免责声明:
我正在学习 Rust,我知道这不是最好的方法。我正在玩耍,看看我能做什么,不能做什么。我也试图限制任何复制来限制我自己。作为oli_obk - ker mentions, this implementation for Conway's Game of Life is flawed .
此代码旨在衡量几件事:
- 如果可能的话
- 如果是惯用的 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/