- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一段代码需要对列表进行操作。此列表包含来自其他来源并需要处理并最终删除的项目。该列表还传递给多个函数,这些函数决定是添加还是删除项目。我创建了一个示例代码来反射(reflect)我的问题:
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);
}
}
这会在运行时发生 panic :
thread 'main' panicked at 'already borrowed: BorrowMutError', src/libcore/result.rs:997:5
我想我理解了这个问题:我有两个不可变借用,然后是第三个可变借用。根据 Rust 文档,这是不允许的:许多不可变借用或单个可变借用。有什么办法可以解决这个问题吗?
最佳答案
我不知道您实际上想要实现什么,因为您未能提供 minimal reproducible example , 但我认为你只是混淆了 list
的借用和 item
在您的数据结构中,这首先让您感到困惑。
尽管如此,以下代码(您可以在 playground 中运行)执行上述操作。
use std::{cell::RefCell, rc::Rc};
pub fn foo() {
let list = Rc::new(RefCell::new(Vec::new()));
let mut list = list.borrow_mut();
let item = Rc::new(RefCell::new(String::from("ABC")));
list.push(item);
println!("list: {:?}", list);
while let Some(item) = list.pop() {
println!("item: {:?}", item);
item.borrow_mut().push_str("DEF");
println!("item: {:?}", item);
}
println!("list: {:?}", list);
}
fn main() {
foo();
}
我在这里使用了两个技巧。
我借了 list
只有一次,借用是可变的,这让我可以从中添加和删除项目。
因为您的描述说您想从 list
中删除项目无论如何,我能够遍历 Vec
与 pop
或 remove
方法(取决于您希望从 list
中获取项目的顺序)。这意味着我不必借用 Vec
对于循环的范围(如果你要迭代它,你会这样做)。
还有其他方法可以根据某些谓词删除元素。例如:Removing elements from a Vec based on some condition .
实际回答您最初的问题:无法同时安全地进行不可变和可变借用。这是 Rust 的核心原则之一,它使内存安全。想一想,如果同时在幕后数据实际上可能发生变化,那么不变性将是一种什么样的保证?
关于rust - 有没有办法同时不可变地和可变地借用 RefCell?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56501086/
Rust 文档涵盖 Rc>相当广泛,但不涉及 RefCell> ,我现在遇到了。 这些是否有效地给出了相同的结果?它们之间有重要区别吗? 最佳答案 Do these effectively give
Rust 文档涵盖 Rc>相当广泛,但不涉及 RefCell> ,我现在遇到了。 这些是否有效地给出了相同的结果?它们之间有重要区别吗? 最佳答案 Do these effectively give
如果我做对了,就不可能通过 std::rc::Rc 创建一个可变的借用。在 Rust 中,你必须使用 Cell或 RefCell .但无论如何我无法理解如何使用它们。例如考虑这个简单的 example
我正在尝试转换 Rc>至 Rc> ( Data 实现 Interface )但在通用方法中是不可能的: use std::cell::RefCell; use std::rc::Rc; trait I
我最初问过这个问题 here , 但它被标记为重复,尽管在我看来它只复制了一部分,所以我创建了一个更具体的: 考虑以下代码: use std::rc::Rc; trait MyTrait {
我正在实现VirtualTapInterface的特征。此特征的receive函数应创建一个TxToken结构,其中lower属性必须是包含当前Rc>的VirtualTapInterface,即sel
我不知道如何在以下代码片段中实现 children_iter: use std::{cell::RefCell, rc::Rc};
我有一段代码需要对列表进行操作。此列表包含来自其他来源并需要处理并最终删除的项目。该列表还传递给多个函数,这些函数决定是添加还是删除项目。我创建了一个示例代码来反射(reflect)我的问题: use
是否可以创建类型为 RefCell 的东西?在使用rust ?我尝试了以下方法: fn test2(x : T) -> RefCell{ return RefCell::new(x) as R
背景 我正在编写一个库,一些相关的代码如下所示: pub struct MyStruct1; pub struct MyStruct2; pub enum MyEnum { Variant1(
这个问题在这里已经有了答案: How do I return a reference to something inside a RefCell without breaking encapsulat
我正在使用Rc>(Playground)实现二进制搜索树 use std::cell::RefCell; use std::rc::Rc; type RcRefBaseNode = Rc>>; typ
我一直在思考为什么 Rust 中的内部可变性在大多数情况下需要运行时检查(例如 RefCell )。看起来我找到了一个没有运行时成本的安全替代方案。我调用类型 SafeCell (主要是因为它是围绕
为什么我们不能将 RefCell 用于 Rust 中的递归数据结构? 无效: enum List { Cons(i32, RefCell), Nil, } 有效: enum List
我有一个包含两个 Vec 的结构,它们被包裹在 RefCell 中。我想在该结构上有一个方法,它结合了两个向量并将它们作为新的 RefCell 或 RefMut 返回: use std::cell::
我正在尝试创建一个方法,该方法返回一个遍历 HashMap 值的迭代器装在 RefCell 内,但我在 Ref 处遇到错误由 RefCell::borrow 返回没有足够长的时间从方法返回迭代器。这是
我试图将 RefCell 传递给闭包中的函数,然后从闭包内部修改同一个变量。这是我的代码: let path: Rc>>> = Rc::new(RefCell::new(None)); ... //v
我有一个包含两个 C 指针和一个 Rust 指针的结构 HashMap . struct MyStruct { p1: *mut ..., p2: *mut ..., hm:
我有一个链表类型的结构,使用 Option、Rc 和 RefCell。 我想为它实现 fmt::Debug,但遇到了可爱的“无法移出借用的内容”错误。 use std::fmt; use std::r
我有一个具有内部可变性的结构。 use std::cell::RefCell; struct MutableInterior { hide_me: i32, vec: Vec, } s
我是一名优秀的程序员,十分优秀!