【问题标题】:Immutable borrow tied to mutable borrow causes "cannot borrow `*self` as mutable more than once at a time" [duplicate]与可变借用相关的不可变借用导致“不能一次多次借用`*self`作为可变”[重复]
【发布时间】:2019-05-21 06:47:03
【问题描述】:

我正在通过练习学习 Rust。在此文件中,目标是像在电子表格中一样更新单元格:当值更改时,必须重新计算从该值派生的所有单元格。在这里,那些被称为那个细胞的父母。

更新单元格值证明没有问题,但更新父母让我与借用检查器作斗争。当我从 HashMap 检索单元格并更新值时,我不再需要可变引用 - 所以我尝试将其包装在不可变引用中。这样我只需要找到一次。

但似乎 Rust 很重要,因为我最初是从借来的 &mut self 中获得了我的不可变引用,它仍然必须与它相关联。这显然会阻止我再次使用self

use std::collections::HashMap;
use std::vec::Vec;

struct Cell {
    value: i32,
    parents: Vec<u32>,
}

pub struct Sheet {
    table: HashMap<u32, Cell>,
}

impl Sheet {
    pub fn set_value(&mut self, identifier: u32, new_value: i32) {
        let mut updated_cell: Option<&Cell> = None;
        if let Some(cell) = self.table.get_mut(&identifier) {
            let Cell { value, .. } = cell;
            *value = new_value;
            updated_cell = Some(cell);
        }
        if let Some(cell) = updated_cell {
            recalculate(self, &cell.parents);
        }
    }
}

fn recalculate(_sheet: &mut Sheet, _cells: &[u32]) {}
error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/lib.rs:20:16
   |
16 |         if let Some(cell) = self.table.get_mut(&identifier) {
   |                             ---------- first mutable borrow occurs here
...
22 |             recalculate(self, &cell.parents);
   |                         ^^^^  ------------- first borrow later used here
   |                         |
   |                         second mutable borrow occurs here

我想知道是否有避免第二次搜索或获取不必要的矢量副本的解决方案。我已经尝试过多次调整代码,但还不是所有的语法我都清楚。

【问题讨论】:

    标签: rust borrow-checker mutability


    【解决方案1】:

    Rust 可以保护您免受潜在的危险情况。 recalculate 的签名中没有任何内容可以保证它不会以 cells 中的引用无效的方式改变 sheet。例如recalculate 可以删除一些单元格,然后cell.parents 中的引用将是悬空指针。

    您可能需要传递父单元的克隆:

    if let Some(cell) = updated_cell {
        let parents = cell.parents.clone();
        recalculate(self, &parents);
    }
    

    或者,您可能需要考虑不同的数据模型,它将单个单元格的可变性与整体结构的可变性分开。例如,您可以将单元格包装在 std::cell::Cellstd::cell::RefCell 中,并将不可变引用传递给 Sheet

    【讨论】:

      猜你喜欢
      • 2023-02-24
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-15
      • 2016-05-02
      相关资源
      最近更新 更多