发生移动是因为树的类型未实现复制特征,值移至此处

问题描述 投票:0回答:1

我知道这是一个关于生锈的多余问题,但似乎我无法从中得到一些普遍性。所以我尝试使用其他地方的一些代码编写一个简单的二叉树(起初我使用了一个选项框,但似乎选项框是可行的方法)。

#[derive(Clone)]
pub struct BinaryTree<T>
where T:Clone
{
    pub val: T,
    pub left : Option<Box<BinaryTree<T>>>,
    pub right : Option<Box<BinaryTree<T>>>,
}

impl<T: std::clone::Clone> BinaryTree<T>
{
    pub fn new(val:T) -> Self
    {
        BinaryTree
        {
            val,
            left:None,
            right:None,
        }
    }

    pub fn insertleft( mut self, node: BinaryTree<T>)-> Self
    {
        //let old_left = mem::take(&mut self.left);
        let left_option = Some(Box::new(node ));
        self.left = left_option;
        self
    }

    pub fn insertright( mut self, node: BinaryTree<T>)-> Self
    {
        let right_option = Some(Box::new( node ));
        self.right = right_option;
        self
    }

}

这就是我的问题。 如果我创建一棵这样的树:

let tree = BinaryTree::new(1).insertleft(BinaryTree::new(2)).insertright(BinaryTree::new(3));

实际上没有问题,我可以毫无问题地访问左值、右值。 但如果我尝试一步步填满树

let tree = BinaryTree::new(1);
tree.insertleft(BinaryTree::new(2));
tree.insertright(BinaryTree::new(3));

然后我会遇到诸如“使用移动值:

tree.left
”之类的错误,无论我是否声明树可变。我真的不明白这棵树应该在哪里或如何被“消耗”在这里。如果我在
& mut ref
ref
函数中使用
insertleft
而不是
insertright
,我会遇到类似的错误,例如无法移出位于可变引用后面的错误。 我读了很多关于此类问题的主题,但我真的不明白为什么你不能通过最终或多或少的 setter 来访问公共领域。

rust reference ownership
1个回答
0
投票

您的

insertleft
insertright
函数采用
self
,这会将
BinaryTree
的所有权转移给这些函数。然后他们将其退回。

如果你想逐步构建树,你可以将这些返回值存储在新变量中以供重复使用:

let tree = BinaryTree::new(1);
let tree = tree.insertleft(BinaryTree::new(2));
let tree = tree.insertright(BinaryTree::new(3));

或者,如果您不需要链式构造和插入,则可以将

&mut
reference 改为
self

impl<T: std::clone::Clone> BinaryTree<T> {
    pub fn insertleft(&mut self, node: BinaryTree<T>) {
        let left_option = Some(Box::new(node));
        self.left = left_option;
    }

    pub fn insertright(&mut self, node: BinaryTree<T>) {
        let right_option = Some(Box::new(node));
        self.right = right_option;
    }
}

fn main() {
    let mut tree = BinaryTree::new(1);
    tree.insertleft(BinaryTree::new(2));
    tree.insertright(BinaryTree::new(3));
}

此引用允许

insertleft
insertright
修改
tree
,将
BinaryTree
的所有权保留在
main
中。但是,您不能再链接构造和插入,因为
BinaryTree::new(1).insertleft(BinaryTree::new(2)).insertright(BinaryTree::new(3))
会产生对临时值的引用。

© www.soinside.com 2019 - 2024. All rights reserved.