如何返回Rc的内容?

问题描述 投票:0回答:1

我正在尝试从

Rc
:

返回移动后的值
if let Some(last_elem) = self.tail.take() {
    let last = Rc::clone(&last_elem);
    let tmp_node = last.borrow();
    let tmp = tmp_node.deref();
    return Some(*tmp);
}

地点:

  • self.tail
    具有类型
    Option<Rc<RefCell<Node<T>>>>
    ;
  • 借用后,
    tmp_node
    具有类型
    Ref<Node<T>>
    ;和
  • 我想回来
    Option<Node<T>>

但是编译器抱怨,“无法移出位于共享引用后面的

*tmp
”。

我该如何解决这个问题?

rust
1个回答
9
投票

一般来说,不可能将某个值移出

Rc
,因为它可能与其他
Rc
共享该值的所有权。

但是,如果您的代码逻辑可以保证这个

Rc
是底层数据的唯一所有者,那么就有一个逃生舱口 -
Rc::try_unwrap
,它在运行时执行检查,如果不满足条件则失败。之后,我们可以轻松地用
RefCell
 打开Ref
(不是
RefCell::into_inner
!):

pub fn unwrap<T>(last_elem: Rc<RefCell<T>>) -> T {
    let inner: RefCell<T> = Rc::try_unwrap(last_elem)
        .unwrap_or_else(|_| panic!("The last_elem was shared, failed to unwrap"));
    inner.into_inner()
}

游乐场


另一种可能的方法,如果您不想从

Rc
移动值而是想要获取副本,则可以采用原来的方法,但使用
clone
而不是
deref

pub fn clone_out<T: Clone>(last_elem: Rc<RefCell<T>>) -> T {
    last_elem.borrow().clone()
}

旁注:看起来您正在尝试实现某种链接列表。在 Rust 中,这是一个众所周知的难题,因为它在单一所有权语义方面表现得非常糟糕。但如果你真的确定你想了解所有肮脏的细节,强烈推荐这本书

© www.soinside.com 2019 - 2024. All rights reserved.