我正在尝试从
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
”。
我该如何解决这个问题?
一般来说,不可能将某个值移出
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 中,这是一个众所周知的难题,因为它在单一所有权语义方面表现得非常糟糕。但如果你真的确定你想了解所有肮脏的细节,强烈推荐这本书。