Передача неизменяемой ссылки, когда существует изменяемая ссылка

У меня есть for цикл, который перебирает кусок Point Структуры. Points будет иметь некоторые поля, измененные в цикле, поэтому функция, содержащая цикл, требует изменяемой ссылки на фрагмент.

Проблема возникает, когда мне нужно передать (неизменяемую) ссылку, указывающую на срез, в функцию внутри цикла 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);
    }
}
Другие вопросы по тегам