如何正确访问RefCell中的值



我想把我的头围绕着RcRefCell在Rust。我想要实现的是有多个可变的引用到相同的对象。

我想出了这个虚拟代码:

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

最有趣的部分是:

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

我更改了fred母亲的名字,然后打印出Susan的名字,这应该是完全相同的引用。令人惊讶的是,它打印出了"Susana",所以我假设我的共享可变引用的小实验是成功的。

然而,现在我想再次改变它,这次访问它作为John的伙伴,这也应该是完全相同的实例。

不幸的是,当我在下面两行注释时:

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

我遇到了我的老朋友cannot move out of dereference of &-pointer。我哪里做错了?

这将修复它:

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

问题是Option<Rc<RefCell>>上的unwrap(),它消耗了选项(即移出它),但你只有一个借来的指针。as_refOption(T)转换为Option(&T), unwrap将其转换为&T,避免任何移动。

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

相关内容

  • 没有找到相关文章

最新更新