我创建了以下具有消耗深度优先遍历的树。

Playpen

struct TreeNode {
    value: i32,
    left: Option<Box<TreeNode>>,
    right: Option<Box<TreeNode>>,
}

fn main() {
    let root = build_tree();
    root.depth_first_pre();
}

fn build_tree() -> TreeNode {
    let root = TreeNode { value: 2,
        left: Some(Box::new(TreeNode { value: 7,
                            left: Some(Box::new(TreeNode { value: 2, left: None, right: None })),
                            right: Some(Box::new(TreeNode { value: 6,
                                                left: Some(Box::new(TreeNode { value: 5, left: None, right: None })),
                                                right: Some(Box::new(TreeNode { value: 11, left: None, right: None })) })) })),
        right: Some(Box::new(TreeNode { value: 5,
                            left: None,
                            right: Some(Box::new(TreeNode { value: 9,
                                                left: Some(Box::new(TreeNode { value: 4, left: None, right: None })),
                                                right: None })) }))};
    return root;
}

impl TreeNode {
    fn depth_first_pre(self) {
        print!("{}, ", self.value);

        if self.left.is_some() {
            self.left.unwrap().depth_first_pre();
        }

        if self.right.is_some() {
            self.right.unwrap().depth_first_pre();
        }
    }
}

Unwrap 从选项中取出值,在这种情况下是可以的,因为每个值只被访问一次。

如果我尝试两次调用该函数,则会出现问题:
root.depth_first_pre();
root.depth_first_pre();

这会导致函数第二次调用出错:
<anon>:10:5: 10:9 error: use of moved value: `root` [E0382]
<anon>:10     root.depth_first_pre();
              ^~~~
<anon>:9:5: 9:9 note: `root` moved here because it has type `TreeNode`, which is non-copyable
<anon>:9     root.depth_first_pre();
             ^~~~
error: aborting due to previous error

我的理解是,它已被第一个函数调用移出,并在超出该函数的作用域后解除分配。

我该如何解决?

我尝试更改函数以引用 self ( &self ) 并将 .unwrap() 更改为 as_ref() 但它没有解决我的问题。

最佳答案

它适用于您建议的更改 添加 as_ref ,而不是用 unwrap 替换 as_ref :

fn depth_first_pre(&self) {
    print!("{}, ", self.value);

    if self.left.is_some() {
        self.left.as_ref().unwrap().depth_first_pre();
    }

    if self.right.is_some() {
        self.right.as_ref().unwrap().depth_first_pre();
    }
}

但是,使用 if let 会更惯用:
fn depth_first_pre(&self) {
    print!("{}, ", self.value);

    if let Some(ref left) = self.left {
       left.depth_first_pre();
    }

    if let Some(ref right) = self.right {
        right.depth_first_pre();
    }
}

关于rust - 将消费树转化为非消费树,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33028424/

10-12 04:41