如何正确访问 RefCell 中的值
Posted
技术标签:
【中文标题】如何正确访问 RefCell 中的值【英文标题】:How to access value in RefCell properly 【发布时间】:2014-10-07 11:29:48 【问题描述】:我试图在 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
&-pointer
。我在这里做错了什么?
【问题讨论】:
【参考方案1】:这将解决它:
boxed_john.borrow().partner.as_ref().unwrap().borrow_mut().name = "Susanna".to_string();
问题是Option<Rc<RefCell>>
上的unwrap()
,它消耗了Option(即移出它),但你只有一个借来的指针。 as_ref
将Option(T)
转换为Option(&T)
和unwrap
将其转换为&T
,避免任何移动。
另请注意:您的变量具有比它们真正需要的更多的可变性。但我确定您已经看到了编译器警告。
【讨论】:
这个语法让我很难过。以上是关于如何正确访问 RefCell 中的值的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Rc<RefCell<_>> 中的具体对象转换为动态特征对象? [复制]