我试图为学习目的实现一个链表。主要使用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,
}
}
我想要实现的是返回位于 struct DbList 的 'first' 中的 struct DbNode 内部的 'data' 值,并将其设置为 'None',如果 'next' 为 None,则将数据所在的 'first' 设置为 'None',否则将 'next' 设置为 'first'。 起初,我尝试使用 Rc::downcast 消耗内部值,但匹配块中 'f' 的类型为 'RefCell' 而不是 'Rc',然后我尝试使用 RefCell::into_inner(),但编译器显示:
我完全理解这是什么意思,但我不知道该怎么做。正确的方法是什么?无法移动出
Rc
移动发生是因为值具有类型为std::cell::RefCell<ds::dll::DbNode<T>>
,它没有实现Copy
trait
f
是一个Rc
。 - kmdrekof
是一个Rc
但是Rc
实现了Deref
来提供对其内部值的直接访问,从而访问它的字段和方法。编译器会透明地完成此操作。这也适用于Box
和甚至Vec
。 - kmdrekof
是Rc,因为有Deref
,我可以将其视为Rc和其内部值,这样说是正确的吗? - ParkCheolu