简体   繁体   English

实现可变的树结构

[英]Implementing a mutable tree structure

I'm trying to dynamically build a tree and modify parts of the tree during descent, at the leaves, and during backup. 我正在尝试动态建立一棵树,并在下降,叶子和备份期间修改树的某些部分。 I believe I have a fundamental misunderstanding on how to do something like this in Rust. 我相信我对在Rust中如何做这样的事情有根本的误解。 Here's my code: 这是我的代码:

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];
        }
    }
}

And this the error message from the compiler: 这是来自编译器的错误消息:

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

There are a few things going on here at the same time. 同时发生了一些事情。 The simple answer is: you are trying to create multiple mutable borrows to the same item. 简单的答案是:您正在尝试为同一项目创建多个可变借项。 Rust forbids you from creating multiple borrows, even if you are not trying to modify them (because that's easier than trying to formally prove that your program is correct). Rust禁止您创建多个借用,即使您不尝试修改它们(因为这比尝试正式证明您的程序正确更容易)。

Since you basically tried to implement a recursive function in an imperative way, I suggest you move to a more functional approach to your problem. 由于您基本上试图以命令式方式实现递归函数,因此建议您使用一种更具功能性的方法来解决问题。 I moved out the logic from your loop into a recursive function that is directly implemented on Node . 我将逻辑从循环中移出,直接在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();
    }
}

If you want to stay imperative, you can use the {node}.children trick to move out of &mut borrows instead of reborrowing them: 如果您想保持当务之急,可以使用{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