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
的引用(请参见下面的代码)

由此,我有两个问题:

  • 在树结构中保留父级引用的正确方法是什么?在C语言中,我会保留一个指向父对象的简单指针,并为子对象保留一些任意集合

  • 在Rust中,如何在同一函数中修改和传递对对象的引用

  • 下面是我的enum和impl的完整代码,还有一个额外的测试函数,可以在不通过它的情况下修改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"),
            }
        }
    }