如何正确访问RefCell中的值

Chr*_*oph 4 smart-pointers rust 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>>>,
    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);

}
Run Code Online (Sandbox Code Playgroud)

最有趣的部分是:

    fred.mother.unwrap().borrow_mut().name = "Susana".to_string();
    println!("{}", boxed_susan.borrow().name)
Run Code Online (Sandbox Code Playgroud)

我更改了Freds母亲的名字,然后打印出Susan的名字,这应该恰好是同一个引用.令人惊讶的是,它打印出"Susana",所以我假设我的共享可变引用的小实验是成功的.

不过,现在我想再次变异这个时候访问它约翰的合作伙伴也应正好是一模一样的实例.

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

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

我正在为我的老朋友cannot move out of dereference of&-pointer.我在这做错了什么?

Rap*_*ien 6

这将解决它:

boxed_john.borrow().partner.as_ref().unwrap().borrow_mut().name = "Susanna".to_string();
Run Code Online (Sandbox Code Playgroud)

问题是unwrap()on Option<Rc<RefCell>>,它消耗Option(即移出它),但你只有一个借来的指针.在as_ref转换Option(T)Option(&T)unwrap其转换为&T,避免任何举动.

另请注意:您的变量具有比实际需要更多的可变性.但我相信你已经看到编译器警告了.

  • 这种语法让我很难过。 (27认同)