免责声明:我刚开始学习锈,我知道这是不是要做到这一点的最好办法。我只是在玩耍,看看我能做什么,不能做什么。我也试图限制任何复制以限制自己。
我有一个&mut Vec<Vec<Cell>>
aka a Board
我想更新它,同时迭代它。 我目前面临的困境是,我想要更新的新值来自一个函数,该函数需要一个&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不允许对对象进行多次可变引用。
所以我的问题是:有没有办法,我能做出这样的代码更新“到位”的board
,就是最内层循环,同时仍然能够调用next_gen
最内层循环内内?
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;
}
}
更新1
因为它已被讨论,这种类型的实施康威生命游戏的是有缺陷的,由ker所强调的意见了。这只是为了衡量一些事情:1)如果这是可能的,2)如果它是惯用的Rust代码。根据我在评论中收集的内容,可以使用std::cell::Cell
。但是,使用std:cell:Cell
则避开了一些Rust原理的核心原则,我在原始问题中将其描述为我的“困境”。
作为文档状态,*内部可变性是最后的手段*,我相信在回落到单元格类型之前还有其他途径可以探索 –
我没有看到Cell是否是最后一招运行时成本。使用不同方法或使用Cell的选择归结为优先选择。 –
这个问题不是运行时成本,它是Rust的借用检查规则的规避,它不仅有助于防止内存不安全,还可以防止修改相同内存位置而导致的意外行为,而不是仅仅在任意位置你有'&mut'引用。想想它有点像C++类成员上的'mutable'关键字。你的非可变对象突然被允许被修改。 –