14

I'm trying to wrap my head around Rc and RefCell in Rust. What I'm trying to achieve is to to have multiple mutable references to the same objects.

I came up with this dummy code:

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

}

The most interesting part is this:

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

I change the name of Freds mother and then print out the name of Susan which should happen to be exactly the same reference. And surprise, surprise it prints out "Susana" so I am assuming that my little experiment of having shared mutable references was successful.

However, now I wanted to mutate it again this time accessing it as the partner of John which should also happen to be exactly the same instance.

Unfortunately when I comment in the following two lines:

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

I'm running into my old friend cannot move out of dereference of&-pointer. What am I doing wrong here?

4

1 回答 1

14

这将解决它:

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

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

另请注意:您的变量具有比它们真正需要的更多的可变性。但我确定您已经看到了编译器警告。

于 2014-08-13T23:53:26.467 回答