根据其他内部字段改变 Rc Refcell 的字段
Mutating fields of Rc Refcell depending on its other internal fields
我需要迭代 Rc RefCell 中结构的一个字段,并根据它的其他字段修改它的一些参数。
例如对于结构 Foo:
pub struct Foo {
pub foo1: Vec<bool>,
pub foo2: Vec<i32>,
}
以下代码出现混乱:
fn main() {
let foo_cell = Rc::new(RefCell::new(Foo { foo1: vec![true, false], foo2: vec![1, 2] }));
foo_cell.borrow_mut().foo2.iter_mut().enumerate().for_each(|(idx, foo2)| {
if foo_cell.borrow().foo1[idx] {
*foo2 *= -1;
}
});
}
我可以通过在可变借用之前克隆 foo1 并仅在闭包内使用克隆来解决它,但这会导致不必要的复制。事实上,我基本上需要一个对 foo2 的可变引用和一个对 foo1 的不可变引用(请注意这是简化的代码,在这里不会压缩迭代器)。我知道代码不符合借用规则。有没有办法在不克隆数据的情况下让它工作?
问题是您试图在每个循环迭代中重新借用 RefCell
,而它已经被借用以使迭代器超过 foo2
。解决方案是在循环之前使用单个 foo_cell.borrow_mut()
并分别借用 foo1
和 foo2
.
请注意,需要取消对 foo_cell.borrow_mut()
的引用才能完成这项工作。
use std::rc::Rc;
use std::cell::RefCell;
pub struct Foo {
pub foo1: Vec<bool>,
pub foo2: Vec<i32>,
}
fn main() {
let foo_cell = Rc::new(RefCell::new(Foo {
foo1: vec![true, false],
foo2: vec![1, 2]
}));
// The dereference is required to get &mut Foo out of the RefMut<Foo>
let borrow = &mut *foo_cell.borrow_mut();
let foo1 = &borrow.foo1;
borrow.foo2.iter_mut().enumerate().for_each(|(idx, foo2)| {
if foo1[idx] {
*foo2 *= -1;
}
});
}
我需要迭代 Rc RefCell 中结构的一个字段,并根据它的其他字段修改它的一些参数。 例如对于结构 Foo:
pub struct Foo {
pub foo1: Vec<bool>,
pub foo2: Vec<i32>,
}
以下代码出现混乱:
fn main() {
let foo_cell = Rc::new(RefCell::new(Foo { foo1: vec![true, false], foo2: vec![1, 2] }));
foo_cell.borrow_mut().foo2.iter_mut().enumerate().for_each(|(idx, foo2)| {
if foo_cell.borrow().foo1[idx] {
*foo2 *= -1;
}
});
}
我可以通过在可变借用之前克隆 foo1 并仅在闭包内使用克隆来解决它,但这会导致不必要的复制。事实上,我基本上需要一个对 foo2 的可变引用和一个对 foo1 的不可变引用(请注意这是简化的代码,在这里不会压缩迭代器)。我知道代码不符合借用规则。有没有办法在不克隆数据的情况下让它工作?
问题是您试图在每个循环迭代中重新借用 RefCell
,而它已经被借用以使迭代器超过 foo2
。解决方案是在循环之前使用单个 foo_cell.borrow_mut()
并分别借用 foo1
和 foo2
.
请注意,需要取消对 foo_cell.borrow_mut()
的引用才能完成这项工作。
use std::rc::Rc;
use std::cell::RefCell;
pub struct Foo {
pub foo1: Vec<bool>,
pub foo2: Vec<i32>,
}
fn main() {
let foo_cell = Rc::new(RefCell::new(Foo {
foo1: vec![true, false],
foo2: vec![1, 2]
}));
// The dereference is required to get &mut Foo out of the RefMut<Foo>
let borrow = &mut *foo_cell.borrow_mut();
let foo1 = &borrow.foo1;
borrow.foo2.iter_mut().enumerate().for_each(|(idx, foo2)| {
if foo1[idx] {
*foo2 *= -1;
}
});
}