Kol*_*lja 6 cyclic-reference rust
我正在尝试在Rust中编写一个容器结构,其中元素也存储对包含容器的引用,以便它们可以在其上调用方法.据我所知,我需要做到这一点Rc<RefCell<T>>.它是否正确?
到目前为止,我有以下内容:
struct Container {
elems: ~[~Element]
}
impl Container {
pub fn poke(&mut self) {
println!("Got poked.");
}
}
struct Element {
datum: int,
container: Weak<RefCell<Container>>
}
impl Element {
pub fn poke_container(&mut self) {
let c1 = self.container.upgrade().unwrap(); // Option<Rc>
let mut c2 = c1.borrow().borrow_mut(); // &RefCell
c2.get().poke();
// self.container.upgrade().unwrap().borrow().borrow_mut().get().poke();
// -> Error: Borrowed value does not live long enough * 2
}
}
fn main() {
let container = Rc::new(RefCell::new(Container{ elems: ~[] }));
let mut elem1 = Element{ datum: 1, container: container.downgrade() };
let mut elem2 = Element{ datum: 2, container: container.downgrade() };
elem1.poke_container();
}
Run Code Online (Sandbox Code Playgroud)
我觉得我在这里错过了一些东西.访问的内容Rc<RefCell<T>>真的很难(在poke_container)?或者我是以错误的方式解决问题的?
最后,并假设的做法是正确的,我怎么会写add的方法Container,以便它可以在填写container领域Element(假设我改变了场为类型Option<Rc<RefCell<T>>>?我不能创建另一个Rc从&mut self据我所知.
方法调用的长链实际上对我来说在 master 上没有任何变化,因为“r-values”的生命周期(例如函数调用的结果)已经改变,因此临时返回值持续到语句结束,而不是比下一个方法调用结束(这似乎是旧规则的工作方式)。
正如弗拉基米尔(Vladimir)暗示的那样,可重载解除引用可能会将其减少到
self.container.upgrade().unwrap().borrow_mut().poke();
Run Code Online (Sandbox Code Playgroud)
哪个更好。
无论如何,用 Rust 编写“改变”共享所有权总是(稍微)困难,无论是单一所有权代码还是不可变的共享所有权代码,因为这样的代码很容易内存不安全(而内存安全是最重要的) Rust 的核心目标)。
| 归档时间: |
|
| 查看次数: |
1035 次 |
| 最近记录: |