我正试图在Rust中围绕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);
}
最有趣的部分是:
fred.mother.unwrap().borrow_mut().name = "Susana".to_string();
println!("{}", boxed_susan.borrow().name)
我更改了Freds母亲的名字,然后打印出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
&amp; -pointer
。我在这里做错了什么?
答案 0 :(得分:5)
这将解决它:
boxed_john.borrow().partner.as_ref().unwrap().borrow_mut().name = "Susanna".to_string();
问题是unwrap()
上的Option<Rc<RefCell>>
,它消耗了Option(即移出它),但你只有一个借来的指针。 as_ref
将Option(T)
转换为Option(&T)
,unwrap
将其转换为&T
,避免任何移动。
另请注意:您的变量具有比实际需要更多的可变性。但我确定你已经看到了编译器警告。