免責聲明:我剛開始學習鏽,我知道這是不是要做到這一點的最好辦法。我只是在玩耍,看看我能做什麼,不能做什麼。我也試圖限制任何複製以限制自己。
我有一個&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'關鍵字。你的非可變對象突然被允許被修改。 –