如何获得对Rc <refcell <t >>树中任意元素的可变引用?

时间:2019-01-29 18:34:06

标签: rust

我的树状结构如下:

use std::{cell::RefCell, collections::HashMap, rc::Rc};

struct Node<T> {
    vals: HashMap<String, T>,
    parent: Option<Rc<RefCell<Node<T>>>>,
}

这是一个链式哈希表:每个节点都包含一个哈希表和一个(可选的,因为树的根没有父级)共享指向其父级的指针。多个孩子可以共享同一个父母。

如果我想从链式哈希图中获取值的克隆,则可以使用递归在树上行走,就像这样:

impl<T> Node<T> {
    pub fn get(&self, name: &str) -> Option<T> {
        self.vals
            .get(name)
            .cloned()
            .or_else(|| self.parent.as_ref().and_then(|p| p.borrow().get(name)))
    }
}

但是,我需要对该树中包含的元素进行可变引用。由于我无法返回对元素的“标准”可变引用,因为它包含在RefCell,中,所以我考虑过使用RefMutRefMut::map函数来获取元素,如下所示:

use std::cell::RefMut;

impl<T> Node<T> {
    pub fn get_mut<'a>(node: RefMut<'a, Node<T>>, name: &str) -> Option<RefMut<'a, T>> {
        if node.vals.contains_key(name) {
            Some(RefMut::map(node, |n| n.vals.get_mut(name).unwrap()))
        } else {
            node.parent.and_then(|p| Node::get_mut(p.borrow_mut(), name))
        }
    }
}

这不会编译:返回值引用其子节点(由于它也依赖于其子节点的借位),并且指向该子节点的RefMut在函数出口处超出范围:

error[E0515]: cannot return value referencing function parameter `p`
  --> src/lib.rs:16:31
   |
16 |                 .and_then(|p| Node::get_mut(p.borrow_mut(), name))
   |                               ^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^
   |                               |             |
   |                               |             `p` is borrowed here
   |                               returns a value referencing data owned by the current function

error[E0507]: cannot move out of borrowed content
  --> src/lib.rs:15:13
   |
15 |             node.parent
   |             ^^^^^^^^^^^ cannot move out of borrowed content

我不知道如何才能从这棵树中得到值得奉献的东西。我假设可能需要某种“ RefMut链”以延长子节点RefMut的生命周期,但是那样也不会创建对同一{的(组成)的多个可变引用) {1}}?

或者,是否有一种方法可以获取指向节点中值之一的某种Node来避免这种依赖性链?我真的对要做的事情感到困惑。

请不要建议传递给给定名称的值而不是返回引用的函数,因为那不适用于我的用例:我真的只需要一个可变的引用(或使我可以获取的东西)一个。)

我不认为这是How do I return a reference to something inside a RefCell without breaking encapsulation?的副本,因为该答案仅涉及返回对单个Rc<RefCell>中包含的值的组成部分的引用(我已经使用{ {1}})。我的问题涉及RefCell链,该问题未解决。

0 个答案:

没有答案