在实现图形时不能借用为可变的,因为它已经被借用了

cannot borrow as mutable because it is already borrowed, when implementing graph

我试图通过让每个节点存储对其邻居的引用来实现图形结构。具体来说,我试图制作一个网格,其中每个节点都引用最多 4 个邻居 - 就像一个“2D 链表”。

但是我在分配引用时遇到错误。这个简约的例子重现了我的问题:

#[derive(Clone)]
struct Node<'a> {
    neighbor: Option<&'a Node<'a>>, // optional reference to another Node
}

fn main() {

    // a bunch of nodes:
    let mut nodes: Vec<Node> = vec![ Node{neighbor: None}; 100];

    // I want node 0 to have a reference to node 1
    nodes[0].neighbor = Some(&nodes[1]);

}

产生以下错误:

error[E0502]: cannot borrow `nodes` as mutable because it is also borrowed as immutable
  --> src/main.rs:12:5
   |
12 |     nodes[0].neighbor = Some(&nodes[1]);
   |     ^^^^^------------------------------
   |     |                         |
   |     |                         immutable borrow occurs here
   |     mutable borrow occurs here
   |     immutable borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.

我正在努力弄清楚这应该如何在 Rust 中完成。我应该改用指针吗?

由于创建借用检查器的原因,您不能完全实现这种数据结构。它告诉你你的数据结构不安全。

它不安全的原因很简单。

假设您创建了一个包含两个元素的图表,第一个引用了第二个。现在你想让第二个引用第一个。要修改图表,您需要获得对该结构的可变访问权限。但是,如果您获得了对它的可变访问权限,就没有什么可以阻止您从图中删除第二个节点,从而使第一个节点中的引用无效。

因此,借阅检查器不允许您这样做。

适合您的方法是使用索引而不是引用。这将有额外的好处:当你想要serialize/deserialize你的结构时,你完全不会有任何问题。