Rust 如何正确访问RefCell中的值

Rust 如何正确访问RefCell中的值,rust,smart-pointers,interior-mutability,Rust,Smart Pointers,Interior Mutability,我正试图用锈迹把我的头缠在Rc和RefCell上。我试图实现的是对同一对象有多个可变引用 我想出了这个伪代码: use std::rc::Rc; use std::cell::RefCell; struct Person { name: String, mother: Option<Rc<RefCell<Person>>>, father: Option<Rc<RefCell<Person>>>,

我正试图用锈迹把我的头缠在
Rc
RefCell
上。我试图实现的是对同一对象有多个可变引用

我想出了这个伪代码:

use std::rc::Rc;
use std::cell::RefCell;

struct Person {
    name: String,
    mother: Option<Rc<RefCell<Person>>>,
    father: Option<Rc<RefCell<Person>>>,
    partner: Option<Rc<RefCell<Person>>>
}

pub fn main () {

    let mut susan = Person {
        name: "Susan".to_string(),
        mother: None,
        father: None,
        partner: None
    };

    let mut boxed_susan = Rc::new(RefCell::new(susan));

    let mut john = Person {
        name: "John".to_string(),
        mother: None,
        father: None,
        partner: Some(boxed_susan.clone())
    };

    let mut boxed_john = Rc::new(RefCell::new(john));

    let mut fred = Person {
        name: "Fred".to_string(),
        mother: Some(boxed_susan.clone()),
        father: Some(boxed_john.clone()),
        partner: None
    };

    fred.mother.unwrap().borrow_mut().name = "Susana".to_string();

    println!("{}", boxed_susan.borrow().name);

    // boxed_john.borrow().partner.unwrap().borrow_mut().name = "Susanna".to_string();
    // println!("{}", boxed_susan.borrow().name);

}
我更改了弗雷德母亲的名字,然后打印出苏珊的名字,这应该是完全相同的参考。令人惊讶的是,它打印出了“Susana”,所以我假设我的共享可变引用的小实验是成功的

然而,现在我想再次对它进行变异,这次作为John的合伙人访问它,这也恰好是同一个实例

不幸的是,当我在下面两行评论时:

// boxed_john.borrow().partner.unwrap().borrow_mut().name = "Susanna".to_string();
// println!("{}", boxed_susan.borrow().name);
我遇到了我的老朋友
无法离开
&
-指针
。我做错了什么?

这会解决问题:

boxed_john.borrow().partner.as_ref().unwrap().borrow_mut().name = "Susanna".to_string();
问题在于
选项
上的
展开()
,它使用该选项(即移出),但您只有一个借用的指针。
as\u ref
选项(T)
转换为
选项(&T)
展开将其转换为
&T
,避免任何移动

还要注意:变量的可变性比它们真正需要的要大得多。但我相信你已经看到了编译器的警告

boxed_john.borrow().partner.as_ref().unwrap().borrow_mut().name = "Susanna".to_string();