簡體   English   中英

實現可變的樹結構

[英]Implementing a mutable tree structure

我正在嘗試動態建立一棵樹,並在下降,葉子和備份期間修改樹的某些部分。 我相信我對在Rust中如何做這樣的事情有根本的誤解。 這是我的代碼:

struct Node {
    children: Vec<Node>,
    data: usize,
}

impl Node {
    pub fn new() -> Node {
        Node {
            children: vec![],
            data: 0,
        }
    }

    pub fn expand(&mut self) {
        self.children = vec![Node::new(), Node::new()];
    }

    pub fn is_leaf(&self) -> bool {
        self.children.len() == 0
    }
}

pub fn main() {
    let mut root = Node::new();
    for _ in 0..10 {
        let mut node = &mut root;
        let mut path = vec![];
        // Descend and potential modify the node in the process
        while !node.is_leaf() {
            let index = 0;
            path.push(index);
            node = &mut node.children[index];
        }
        // Do something to the leaf node
        node.expand();
        // Do something during "backup" (in my case it doesn't matter
        // in which order the modification is happening).
        node = &mut root;
        for &i in path.iter() {
            node.data += 1;
            node = &mut node.children[i];
        }
    }
}

這是來自編譯器的錯誤消息:

error[E0502]: cannot borrow `*node` as immutable because `node.children` is also borrowed as mutable
  --> src/main.rs:29:16
   |
29 |         while !node.is_leaf() {
   |                ^^^^ immutable borrow occurs here
...
32 |             node = &mut node.children[index];
   |                         ------------- mutable borrow occurs here
...
43 |     }
   |     - mutable borrow ends here

error[E0506]: cannot assign to `node` because it is borrowed
  --> src/main.rs:32:13
   |
32 |             node = &mut node.children[index];
   |             ^^^^^^^^^^^^-------------^^^^^^^
   |             |           |
   |             |           borrow of `node` occurs here
   |             assignment to borrowed `node` occurs here

error[E0499]: cannot borrow `node.children` as mutable more than once at a time
  --> src/main.rs:32:25
   |
32 |             node = &mut node.children[index];
   |                         ^^^^^^^^^^^^^
   |                         |
   |                         second mutable borrow occurs here
   |                         first mutable borrow occurs here
...
43 |     }
   |     - first borrow ends here

error[E0499]: cannot borrow `*node` as mutable more than once at a time
  --> src/main.rs:35:9
   |
32 |             node = &mut node.children[index];
   |                         ------------- first mutable borrow occurs here
...
35 |         node.expand();
   |         ^^^^ second mutable borrow occurs here
...
43 |     }
   |     - first borrow ends here

error[E0506]: cannot assign to `node` because it is borrowed
  --> src/main.rs:38:9
   |
32 |             node = &mut node.children[index];
   |                         ------------- borrow of `node` occurs here
...
38 |         node = &mut root;
   |         ^^^^^^^^^^^^^^^^ assignment to borrowed `node` occurs here

error[E0499]: cannot borrow `root` as mutable more than once at a time
  --> src/main.rs:38:21
   |
26 |         let mut node = &mut root;
   |                             ---- first mutable borrow occurs here
...
38 |         node = &mut root;
   |                     ^^^^ second mutable borrow occurs here
...
43 |     }
   |     - first borrow ends here

error[E0506]: cannot assign to `node` because it is borrowed
  --> src/main.rs:41:13
   |
32 |             node = &mut node.children[index];
   |                         ------------- borrow of `node` occurs here
...
41 |             node = &mut node.children[i];
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `node` occurs here

error[E0499]: cannot borrow `node.children` as mutable more than once at a time
  --> src/main.rs:41:25
   |
32 |             node = &mut node.children[index];
   |                         ------------- first mutable borrow occurs here
...
41 |             node = &mut node.children[i];
   |                         ^^^^^^^^^^^^^ second mutable borrow occurs here
42 |         }
43 |     }
   |     - first borrow ends here

同時發生了一些事情。 簡單的答案是:您正在嘗試為同一項目創建多個可變借項。 Rust禁止您創建多個借用,即使您不嘗試修改它們(因為這比嘗試正式證明您的程序正確更容易)。

由於您基本上試圖以命令式方式實現遞歸函數,因此建議您使用一種更具功能性的方法來解決問題。 我將邏輯從循環中移出,直接在Node實現的遞歸函數。

struct Node {
    children: Vec<Node>,
    data: usize,
}

impl Node {

    pub fn new() -> Node {
        Node {
            children: vec!(),
            data: 0
        }
    }

    pub fn expand(&mut self) {
        self.children = vec!(Node::new(), Node::new());
    }

    pub fn is_leaf(&self) -> bool {
        self.children.len() == 0
    }

    fn expand_leaf_and_inc(&mut self) {
        if self.is_leaf() {
            self.expand();
        } else {
            let index = 0;
            self.children[index].expand_leaf_and_inc();
        }
        self.data += 1
    }
}

pub fn main() {
    let mut root = Node::new();
    for _ in 0..10 {
        root.expand_leaf_and_inc();
    }
}

如果您想保持當務之急,可以使用{node}.children技巧擺脫&mut借用,而不必重新借用它們:

let mut root = Node::new();
for _ in 0..10 {
    let mut path = vec![];
    {
        let mut node = &mut root;
        // Descend and potential modify the node in the process
        while !node.is_leaf() {
            let index = 0;
            path.push(index);
            node = &mut {node}.children[index];
        }
        // Do something to the leaf node
        node.expand();
    }
    // Do something during "backup" (in my case it doesn't matter
    // in which order the modification is happening).
    let mut node = &mut root;
    for &i in path.iter() {
        node.data += 1;
        node = &mut {node}.children[i];
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM