Rust 如何使用Rc<;的数据类型;RefCell<;T>&燃气轮机;在结构中?

Rust 如何使用Rc<;的数据类型;RefCell<;T>&燃气轮机;在结构中?,rust,Rust,我正在尝试实现一个用于学习目的的链表。std::cell::RefCell和stc::rc:{rc,Weak}主要用于将数据存储到列表实例中。现在我正在实现fnpop,它使用并返回列表中第一个位置的值,但我不知道如何使用用Rc和RefCell包装的值 这是我的密码: use std::cell::RefCell; use std::rc::{Rc, Weak}; #[derive(Debug)] pub struct DbNode<T> { data: T, nex

我正在尝试实现一个用于学习目的的链表。std::cell::RefCell和stc::rc:{rc,Weak}主要用于将数据存储到列表实例中。现在我正在实现fnpop,它使用并返回列表中第一个位置的值,但我不知道如何使用用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,
    }
}
使用std::cell::RefCell;
使用std::rc::{rc,弱};
#[导出(调试)]
发布结构DbNode{
数据:T,
下一步:选择,
上:期权,
}
#[导出(调试)]
发布结构数据库列表{
第一:选择,
最后:选择,,
}
发布fn推送前(和多个自身,数据:T){
匹配self.first.take(){
一些(e)=>{
让new_front=Rc::new(RefCell::new(DbNode{
数据,
下一步:一些(如克隆()),
上一篇:没有,
}));
让我们共同学习;
me.prev=Some(Rc::降级(&new_front));
self.first=一些(新的前);
},
无=>{
让new_data=Rc::new(RefCell::new(DbNode{
数据,
下一个:没有,
上一篇:没有,
}));
self.last=Some(Rc::降级(&new_数据));
self.first=一些(新的_数据);
},
}
}
发布fn推回(&mut self,数据:T){
匹配self.last.take(){
一些(l)=>{
让new_返回=Rc::new(RefCell::new(DbNode{
数据,
下一个:没有,
prev:Some(l.clone()),
}));
让st=Weak::upgrade(&l).unwrap();
设mut ml=st.borrow_mut();
self.last=Some(Rc::降级(&new_back));
ml.next=Some(新返回);
},
无=>{
让new_data=Rc::new(RefCell::new(DbNode{
数据,
下一个:没有,
上一篇:没有,
}));
self.last=Some(Rc::降级(&new_数据));
self.first=一些(新的_数据);
},
}
}
pub fn pop(&mut self)->选项{
匹配self.first.take(){
一些(f)=>{
//我怎么能??
//让结果=一些(f.进入_inner().数据);
//结果
},
无=>无,
}
}
我想要实现的是返回structDbNode中位于structDbList的“first”中的内部“data”值,并将None设置为要使用的数据所在的“first”,如果“next”是None,则将“next”设置为“first”。 起初,我尝试使用Rc::downcast使用内部值,但匹配块中的“f”类型是“RefCell”,而不是“Rc”,然后我尝试使用RefCell::into_inner(),但编译器说:

无法移出
Rc
发生移动是因为值的类型为
std::cell::RefCell
,而该类型不实现
Copy
特性

我完全理解这意味着什么,但我不知道我该怎么做。正确的方法是什么???

你很接近。使用:

如果
Rc
正好有一个强引用,则返回内部值。否则,返回的
Err
与传入的
Rc
相同。即使存在突出的弱引用,这也会成功

pub-fn-pop(&mut-self)->选项{
匹配self.first.take(){
一些(f)=>{
匹配Rc::尝试展开(f){
正常(参考单元格)=>{
//您可以在此处执行refcell.into_inner
一些(refcell.into_inner().data)
},
错误(41;)=>{
//另一个Rc仍然存在,因此您无法获得该值的所有权
没有一个
}
}
},
无=>无,
}
}

很有效,非常感谢!我还有一个问题:如何在选项匹配中获得Rc而不是RefCell?据我所知,它是RefCell,因为它是自动取消引用的。如果我想得到Rc,我能做些什么呢?@parksheolu我不明白,在这个示例中,
f
是一个
Rc
。真的吗?如果是这样,我的VisualStudio很奇怪。当我在“f”之后键入dot时,IDE会显示RefCell的方法列表,而不是Rc…这是由于取消引用,
f
是一个
Rc
,但是
Rc
s实现了
Deref
的内部值,提供了对字段和方法的直接访问。这是由编译器透明地完成的。这也用于
Box
s,甚至
Vec
s。我知道了。你说得对。我刚刚检查了Rc::try_unwrap in docs,它只接受Rc。所以,“
f
是Rc,我可以将它视为Rc和它的内部值,因为
Deref
”是正确的吗?
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,
    }
}