如何解决错误 ‘already mutably borrowed: BorrowError’

huangapple go评论72阅读模式
英文:

how to solve the error 'already mutably borrowed: BorrowError'

问题

我不太擅长处理Rust中的RefCell,我想知道如何解决以下错误。

如果有人能回答我的问题,我将非常感激。

thread 'main' panicked at 'already mutably borrowed: BorrowError', src/main.rs:47:22

rust playground

英文:

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}");
}

rust playground

答案1

得分: 2

来自URLO的交叉帖子

以下是一个安全的解决方案:

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");
    }
}

playground

英文:

Came from a cross post in URLO

And here's a safe solution:

let i = {
    // b update c.v
    let ref_i = RefCell::borrow(&amp;self.i); // RefCell::&lt;I&gt;::borrow::&lt;&#39;r&gt;(&amp;&#39;r self) -&gt; Ref&lt;&#39;r, I&gt;
    ref_i.b.i.clone() // throw away &#39;r via cloning Weak
};
update_cv_from_b(&amp;i);

fn update_cv_from_b(i: &amp;Weak&lt;RefCell&lt;I&gt;&gt;) {
    if let Some(i) = i.upgrade() {
        let mut ii = RefCell::borrow_mut(&amp;i);
        ii.c.v.push_str(&quot;b.udpate_cv&quot;);
    }
}

playground

huangapple
  • 本文由 发表于 2023年2月27日 08:28:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575891.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定