![](/img/trans.png)
[英]How can I implement Deref for a struct that holds an Rc<Refcell<Trait>>?
[英]How can I consume data type of Rc<RefCell<T>> in struct?
我正在尝试实现一个用于学习目的的链接列表。 std::cell::RefCell 和 stc::rc::{Rc, Weak} 主要用于将数据存储到列表实例中。 现在我正在实现fn pop ,它在列表的第一个位置使用并返回一个值,但我不知道如何使用用 Rc 和 RefCell 包装的值。
这是我的代码:
use std::cell::RefCell;
use std::rc::{Rc, Weak};
#[derive(Debug)]
pub struct DbNode<T> {
data: T,
next: Option<Rc<RefCell<DbNode<T>>>>,
prev: Option<Weak<RefCell<DbNode<T>>>>,
}
#[derive(Debug)]
pub struct DbList<T> {
first: Option<Rc<RefCell<DbNode<T>>>>,
last: Option<Weak<RefCell<DbNode<T>>>>,
}
pub fn push_front(&mut self, data: T) {
match self.first.take() {
Some(e) => {
let new_front = Rc::new(RefCell::new(DbNode {
data,
next: Some(e.clone()),
prev: None,
}));
let mut me = e.borrow_mut();
me.prev = Some(Rc::downgrade(&new_front));
self.first = Some(new_front);
},
None => {
let new_data = Rc::new(RefCell::new(DbNode {
data,
next: None,
prev: None,
}));
self.last = Some(Rc::downgrade(&new_data));
self.first = Some(new_data);
},
}
}
pub fn push_back(&mut self, data: T) {
match self.last.take() {
Some(l) => {
let new_back = Rc::new(RefCell::new(DbNode {
data,
next: None,
prev: Some(l.clone()),
}));
let st = Weak::upgrade(&l).unwrap();
let mut ml = st.borrow_mut();
self.last = Some(Rc::downgrade(&new_back));
ml.next = Some(new_back);
},
None => {
let new_data = Rc::new(RefCell::new(DbNode {
data,
next: None,
prev: None,
}));
self.last = Some(Rc::downgrade(&new_data));
self.first = Some(new_data);
},
}
}
pub fn pop(&mut self) -> Option<T> {
match self.first.take() {
Some(f) => {
// How can I??
// let result = Some(f.into_inner().data);
// result
},
None => None,
}
}
我想要实现的是返回结构 DbNode 中位于 struct DbList中“第一个”中的内部“数据”值,并将None设置为“第一个”,如果“下一个”为None ,则要消耗的数据位于该第一个,否则将“下一个”设置为“第一个”。 起初,我尝试使用Rc::downcast来消耗内部值,但匹配块中 'f' 的类型是 'RefCell',而不是 'Rc',然后我尝试使用 RefCell::into_inner(),但是编译器说:
无法移出
Rc
移动,因为 value 的类型为std::cell::RefCell<ds::dll::DbNode<T>>
,它没有实现Copy
trait
我完全理解这意味着什么,但我不知道我应该怎么做。 正确的做法是什么??
你很亲密。 使用Rc::try_unwrap()
:
如果
Rc
恰好有一个强引用,则返回内部值。 否则,将返回带有传入相同Rc
的Err
。即使存在未完成的弱引用,这也会成功。
pub fn pop(&mut self) -> Option<T> {
match self.first.take() {
Some(f) => {
match Rc::try_unwrap(f) {
Ok(refcell) => {
// you can do refcell.into_inner here
Some(refcell.into_inner().data)
},
Err(_) => {
// another Rc still exists so you cannot take ownership of the value
None
}
}
},
None => None,
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.