0

我正在尝试创建一个可变结构B,该结构存储其他结构的实例,这些结构A包含对B. 我想要一个实现,使得对原始文件所做的任何突变都会B传播到As 中保存的引用。

但是,在突变期间,我必须检查包含B在实例中的实例中的字段A,从而打破“一个可变 x 或多个不可变”规则。我需要在可变借用时不可变地借用,但是不可变借用是变异函数的内部,并且不会超出其范围。

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

#[derive(Debug)]
struct A {
    t: Weak<RefCell<B>>,
}

#[derive(Debug)]
struct B {
    a: usize,
    item: Option<A>,
}

impl B {
    pub fn mutate(&mut self, item: A) {
        {
            let t = item.t.upgrade().unwrap();

            // This check has to be done.
            //
            assert![t.borrow().a == self.a, "not equal"];
            //      ~~~~~~~~~~ panics on this borrow
        }
        //
        // The immutable borrow should end here.

        self.item = Some(item);
        self.a += 1;
    }
}

fn main() {
    let b = B { item: None, a: 0 };

    let bc = Rc::new(RefCell::new(b));

    let f = A {
        t: Rc::downgrade(&bc),
    };

    bc.borrow_mut().mutate(f);

    println!["{:?}", bc.borrow().item.as_ref().unwrap().t.upgrade()];
}

操场

它恐慌:

thread 'main' panicked at 'already mutably borrowed: BorrowError'

仅使用 可以满足这些要求Rc<RefCell<B>>吗?如果没有,我是否必须沉浸在unsafe代码中?

4

1 回答 1

2

文档RefCell::borrow说:

恐慌

如果该值当前被可变借用,则会出现恐慌。对于非恐慌变体,使用try_borrow.

使用try_borrow任何现有借用必须是self(因此是相等的)的知识允许您的代码编译:

let eq = t.try_borrow().map_or(true, |v| v.a == self.a);
assert![eq, "not equal"];

也可以看看:

于 2020-03-25T20:29:43.483 回答