我知道这是一个关于生锈的多余问题,但似乎我无法从中得到一些普遍性。所以我尝试使用其他地方的一些代码编写一个简单的二叉树(起初我使用了一个选项框,但似乎选项框是可行的方法)。
#[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 来访问公共领域。
您的
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))
会产生对临时值的引用。