Rust 有没有办法同时以不变和可变方式借用RefCell?

Rust 有没有办法同时以不变和可变方式借用RefCell?,rust,rc,borrow,refcell,Rust,Rc,Borrow,Refcell,我有一段代码需要在列表上操作。此列表包含来自其他来源的项目,需要处理并最终删除。该列表还传递给多个函数,这些函数决定是否添加或删除项目。我创建了一个反映我的问题的示例代码: use std::{cell::RefCell, rc::Rc}; pub fn foo() { let list: Rc<RefCell<Vec<Rc<RefCell<String>>>>> = Rc::new(RefCell::new(Vec::new

我有一段代码需要在列表上操作。此列表包含来自其他来源的项目,需要处理并最终删除。该列表还传递给多个函数,这些函数决定是否添加或删除项目。我创建了一个反映我的问题的示例代码:

use std::{cell::RefCell, rc::Rc};

pub fn foo() {
    let list: Rc<RefCell<Vec<Rc<RefCell<String>>>>> = Rc::new(RefCell::new(Vec::new()));

    list.borrow_mut()
        .push(Rc::new(RefCell::new(String::from("ABC"))));

    while list.borrow().len() > 0 {
        let list_ref = list.borrow();

        let first_item = list_ref[0].borrow_mut();
        //item processing, needed as mutable

        list.borrow_mut().remove(0);
    }
}

我想我理解这个问题:我有两个不可变的借词,还有第三个是可变的。根据Rust文档,这是不允许的:要么是许多不可变的借用,要么是单个可变的借用。有什么办法可以绕过这个问题吗?

我不知道您实际上想要实现什么,因为您没有提供一个解决方案,但我认为您只是混淆了数据结构中
列表
的借用,这首先让您感到困惑

尽管如此,下面的代码(可以在中运行)实现了上面所述的功能

使用std:{cell::RefCell,rc::rc};
pub fn foo(){
let list=Rc::new(RefCell::new(Vec::new());
让mut list=list.borrow_mut();
让item=Rc::new(RefCell::new(String::from(“ABC”));
列表。推送(项目);
println!(“列表:{:?}”,列表);
而let Some(item)=list.pop(){
println!(“项:{:?}”,项);
项目。借用(mut()。推送(DEF);
println!(“项:{:?}”,项);
}
println!(“列表:{:?}”,列表);
}
fn main(){
foo();
}
这里我用了两个技巧

  • 我只借用了一次
    列表
    ,而且该借用是可变的,允许我从中添加和删除项目

  • 因为您的描述说您无论如何都要从
    列表中删除项目,所以我能够使用
    pop
    remove
    方法(取决于您希望从
    列表中获取项目的顺序)在
    Vec
    上进行迭代。这意味着对于循环的范围,我不必借用
    Vec
    (否则,如果对它进行迭代,就会这样做)

  • 还有其他方法可以基于某个谓词删除元素。例如:


    要真正回答您最初的问题:不可能同时安全地拥有一个不变的和可变的借用。这是Rust的核心原理之一,使其具有内存安全性。想想看,如果同时,在幕后,数据实际上可能会发生变化,那么不变性将是一种什么样的保证?

    我今天才完成了这本铁锈书,我可能是在胡说八道,为什么不通过可变借阅来实现这一点呢?