Передача неизменяемой ссылки, когда существует изменяемая ссылка
У меня есть for
цикл, который перебирает кусок Point
Структуры. Point
s будет иметь некоторые поля, измененные в цикле, поэтому функция, содержащая цикл, требует изменяемой ссылки на фрагмент.
Проблема возникает, когда мне нужно передать (неизменяемую) ссылку, указывающую на срез, в функцию внутри цикла for, которая выполняет итерацию по изменяемой ссылке:
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let mut grid = vec![];
grid.push(Point { x: 10, y: 10 });
grid.push(Point { x: -1, y: 7 });
calculate_neighbors(&mut grid);
}
fn calculate_neighbors(grid: &mut [Point]) {
for pt in grid.iter_mut() {
pt.x = nonsense_calc(grid);
}
}
#[allow(unused_variables)]
fn nonsense_calc(grid: &[Point]) -> i32 {
unimplemented!();
}
error[E0502]: cannot borrow `*grid` as immutable because it is also borrowed as mutable
--> src/main.rs:18:30
|
17 | for pt in grid.iter_mut() {
| ---------------
| |
| mutable borrow occurs here
| mutable borrow used here, in later iteration of loop
18 | pt.x = nonsense_calc(grid);
| ^^^^ immutable borrow occurs here
Компилятор жалуется, что grid
не может быть заимствовано как неизменное, потому что изменяемый заем уже существует. Это правильно, и я вижу проблему, которую он пытается предотвратить, но как мне добиться того, что мне нужно сделать? В идеале мне не нужно создавать копию grid
, как это может быть дорого.
1 ответ
Решение, чтобы избежать заимствования массива для итерации, было бы использовать индексы:
fn calculate_neighbors(grid: &mut [Point]) {
for i in 0..grid.len() {
grid[i].x = nonsense_calc(grid);
}
}