英文:
how to solve the error 'already mutably borrowed: BorrowError'
问题
我不太擅长处理Rust中的RefCell
,我想知道如何解决以下错误。
如果有人能回答我的问题,我将非常感激。
thread 'main' panicked at 'already mutably borrowed: BorrowError', src/main.rs:47:22
英文:
I'm not very skilled with rust RefCell
and i want to know how to solve the following error.
I would be very grateful if someone could answer my question.
thread 'main' panicked at 'already mutably borrowed: BorrowError', src/main.rs:47:22
use std::{
cell::RefCell,
rc::{Rc, Weak},
};
// parent
struct P {
i: Rc<RefCell<I>>,
}
impl P {
fn new() -> P {
let b = B {
v: "b".to_string(),
i: Weak::new(),
};
let c = C {
v: "c".to_string(),
i: Weak::new(),
};
let i = Rc::new(RefCell::new(I { b, c }));
let ii = i.clone();
let p = P { i };
// init b.i
let mut borrow_mut = RefCell::borrow_mut(&ii);
let bb = &mut borrow_mut.b;
bb.i = Rc::downgrade(&ii);
// init c.i
let cc = &mut borrow_mut.c;
cc.i = Rc::downgrade(&ii);
p
}
fn update_bv_cv(&self) {
// update b.v
let mut borrow_mut = RefCell::borrow_mut(&self.i);
let b = &mut borrow_mut.b;
b.v.push_str("=>p.update_bv_cv");
// update c.v
let c = &mut borrow_mut.c;
c.v.push_str("=>p.update_bv_cv");
// b update c.v
let borrow = RefCell::borrow(&self.i);
let b = &borrow.b;
b.update_cv();
}
fn get_bv_cv(&self) -> (String, String) {
let i = &self.i;
let ii = i.borrow();
let bv = ii.b.v.as_str();
let cv = ii.c.v.as_str();
(bv.into(), cv.into())
}
}
// parent inner
struct I {
c: C,
b: B,
}
// child
struct C {
i: Weak<RefCell<I>>,
v: String,
}
// child
struct B {
i: Weak<RefCell<I>>,
v: String,
}
impl B {
fn update_cv(&self) {
if let Some(i) = self.i.upgrade() {
let mut ii = RefCell::borrow_mut(&i);
ii.c.v.push_str("b.udpate_cv");
}
}
}
fn main() {
let p = P::new();
p.update_bv_cv();
let (bv, cv) = p.get_bv_cv();
println!("b.v: {bv}\nc.v: {cv}");
}
答案1
得分: 2
以下是一个安全的解决方案:
let i = {
// b更新c.v
let ref_i = RefCell::borrow(&self.i); // RefCell::<I>::borrow::<'r>(&'r self) -> Ref<'r, I>
ref_i.b.i.clone() // 通过克隆Weak来丢弃 'r
};
update_cv_from_b(&i);
fn update_cv_from_b(i: &Weak<RefCell<I>>) {
if let Some(i) = i.upgrade() {
let mut ii = RefCell::borrow_mut(&i);
ii.c.v.push_str("b.udpate_cv");
}
}
英文:
Came from a cross post in URLO
And here's a safe solution:
let i = {
// b update c.v
let ref_i = RefCell::borrow(&self.i); // RefCell::<I>::borrow::<'r>(&'r self) -> Ref<'r, I>
ref_i.b.i.clone() // throw away 'r via cloning Weak
};
update_cv_from_b(&i);
fn update_cv_from_b(i: &Weak<RefCell<I>>) {
if let Some(i) = i.upgrade() {
let mut ii = RefCell::borrow_mut(&i);
ii.c.v.push_str("b.udpate_cv");
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论