【问题标题】:Passing an immutable reference when a mutable reference exists当可变引用存在时传递不可变引用
【发布时间】:2018-12-20 15:29:04
【问题描述】:

我有一个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!();
}

Playground

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 的副本,因为这可能很昂贵。

【问题讨论】:

    标签: loops rust borrow-checker mutability


    【解决方案1】:

    避免借用数组进行迭代的解决方案是使用索引:

    fn calculate_neighbors(grid: &mut [Point]) {
        for i in 0..grid.len() {
            grid[i].x = nonsense_calc(grid);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      • 2023-01-07
      相关资源
      最近更新 更多