Rust 将&;变自我
我是个新手,作为学习过程的一部分,我正在尝试创建一个树结构,其中每个节点都有一个子节点向量和对其父节点的引用。我想为节点创建一个Rust 将&;变自我,rust,mutable,borrow-checker,borrowing,Rust,Mutable,Borrow Checker,Borrowing,我是个新手,作为学习过程的一部分,我正在尝试创建一个树结构,其中每个节点都有一个子节点向量和对其父节点的引用。我想为节点创建一个addChild()函数,该函数接受新节点的值(i32s,现在是),将其添加到子列表中,并将引用作为父节点传递给自身。下面是Rust by Example,我试图用一个框引用父对象。由于我正在修改父对象并向其传递一个引用,所以我被卡住了,因为借阅检查器不希望我取消对&mut self的引用(请参见下面的代码) 由此,我有两个问题: 在树结构中保留父级引用的正确方法是什么
addChild()
函数,该函数接受新节点的值(i32
s,现在是),将其添加到子列表中,并将引用作为父节点传递给自身。下面是Rust by Example,我试图用一个框
引用父对象。由于我正在修改父对象并向其传递一个引用,所以我被卡住了,因为借阅检查器不希望我取消对&mut self
的引用(请参见下面的代码)
由此,我有两个问题:
#[派生(散列、等式、PartialEq)]
枚举节点{
元素{
值:i32,
家长:盒子,
儿童:Vec,
},
无
}
impl节点{
fn新建(值:i32,父项:框)->节点{
返回节点::Elem{
价值:价值,
家长:家长,
子项:Vec::new(),
};
}
//此函数工作正常
fn设置值(&mut self,v:i32){
匹配自我{
&mut Node::Elem{ref mut value,…}=>*value=v,
&mut节点::Nil=>{}
}
}
fn addChild(&mut self,值:i32){
匹配自我{
&mut Node::Elem{ref mut children,…}=>{
(*子项).push(节点::新建(值,框::新建(*self)))
//生成E0507(无法移出借用的上下文)
}
&mut Node::Nil=>println!(“未能将子节点添加到空节点”),
}
}
}
树在Rust中是非常自然的数据结构,但是当您向树添加父指针时,您就有了一个图形。因为每个节点的所有权变得非常模糊,所以图形要困难得多。请检查一些现有问题(、、还有更多),然后将其标记为重复问题或您的问题来解释差异。@Shepmaster谢谢。目标不是创建一个搜索树,而是创建一个独立对象的完整的可追溯树结构。在你的第一篇博文中,被接受的答案以“你不能在安全的rust中表示任意的图形结构”开头。真的是这样吗?我是说。。这是一种非常基本的表达关系的方式。没有任何方法可以指向一个对象而不拥有它吗?@dromtrund使用弱引用计数器可以做一些事情,但老实说,在大多数情况下,处理不安全的和原始指针可能对您的理智更好,只要您不向用户公开不安全的部分。我从未提到过的另一种方法是将树节点存储在Vec
或其他什么东西中,并为每个节点分配一个唯一的可复制的ID,然后,不必持有子/父指针,只需存储子/父的ID即可。请看哪一个应该引导您完成一些不同的解决方案。
#[derive(Hash, Eq, PartialEq)]
enum Node {
Elem {
value: i32,
parent: Box<Node>,
children: Vec<Node>,
},
Nil,
}
impl Node {
fn new(value: i32, parent: Box<Node>) -> Node {
return Node::Elem {
value: value,
parent: parent,
children: Vec::new(),
};
}
// This function works fine
fn setValue(&mut self, v: i32) {
match self {
&mut Node::Elem { ref mut value, .. } => *value = v,
&mut Node::Nil => {}
}
}
fn addChild(&mut self, value: i32) {
match self {
&mut Node::Elem { ref mut children, .. } => {
(*children).push(Node::new(value, Box::new(*self)))
// Produces E0507 (Cannot move out of borrowed context)
}
&mut Node::Nil => println!("Failed to add children to empty node"),
}
}
}