装箱对 & self 的引用

Boxing a reference to &mut self

提问人:dromtrund 提问时间:5/5/2016 最后编辑:Shepmasterdromtrund 更新时间:5/5/2016 访问量:700

问:

我是 Rust 的新手,作为学习过程的一部分,我正在尝试创建一个树结构,其中每个节点都有一个子节点的向量和对其父节点的引用。我想为节点创建一个函数,该函数采用新节点的值(暂时),将其添加到子列表,并将对自身的引用作为父节点传递。在 Rust by Example 的链表示例之后,我尝试用 .由于我既要修改父级又要传递对它的引用,所以我被卡住了,因为借用检查器不希望我取消引用(请参阅下面的代码)。addChild()i32Box<>&mut self

由此我有两个问题:

  1. 在树结构中保留对父项的引用的正确方法是什么?在 C 语言中,我会保留一个指向父项的简单指针和一些子项的任意集合。

  2. 在 Rust 中,您应该如何修改和传递对同一函数中对象的引用?

下面是我的枚举和 impl 的完整代码,还有一个额外的测试函数来修改 self,而无需传递它。


#[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"),
        }
    }
}
可变 借用检查器 借贷

评论

4赞 Shepmaster 5/5/2016
是 Rust 中非常自然的数据结构,但是当你向树添加父指针时,你就会得到一个图表。图形要困难得多,因为每个节点的所有权变得非常模糊。请查看一些现有问题(12345 等等),然后将其标记为重复或编辑您的问题以解释差异。
0赞 dromtrund 5/6/2016
@Shepmaster谢谢。目标不是创建一个搜索树,而是创建一个完整的可回溯独立对象的树结构。在你的第一篇文章中,公认的答案是“你不能在安全锈蚀中表示任意的图形结构”。真的是这样吗?我的意思是。。这是表示关系的一种非常基本的方式。难道没有办法在不拥有对象的情况下指向它吗?
2赞 Linear 5/6/2016
@dromtrund 你可以用弱引用计数器做一些事情,但老实说,在大多数情况下,只要你不向用户暴露不安全的位,使用原始指针可能对你的理智更好。unsafe
2赞 Linear 5/6/2016
我从未见过的另一种方法是将树节点存储在一个或某物中,并为每个节点分配一个唯一的 ID,然后不按住子/父指针,只需存储子/父的 ID。VecCopy
2赞 Veedrac 5/6/2016
请参阅学习 Rust with Totally Too Too Linked List,它应该会引导你完成一些不同的解决方案。

答: 暂无答案