Link to the containing structure in Rust (and calling methods on it)

I am trying to write a container structure in Rust, where its elements also store a reference to the containing container so that they can call methods on it. As far as I can understand, I need to do this via Rc<RefCell<T>> . Is it correct?

So far, I have something like the following:

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

I feel that something is missing here. Is access to the contents of Rc<RefCell<T>> really complicated (in poke_container )? Or am I getting the problem wrong?

Finally, assuming the approach is correct, how would I write the add method for Container so that it can fill the Container field in Element (assuming I changed the field like Option<Rc<RefCell<T>>> ? I can't create another Rc from &mut self , as far as I know.

+6
source share
1 answer

Long method calls actually work for me on the main thing without any changes, because the lifetime of the "r-values" (for example, the result of function calls) has changed, so that the temporary return values ​​continue until the end and not the end of the next method call ( which seemed to work with the old rule).

According to Vladimir, overloaded dereferencing is likely to reduce it to

 self.container.upgrade().unwrap().borrow_mut().poke(); 

which is better.

In any case, “mutating” shared ownership will always be (a little) harder to write in Rust that either one ownership code or an immutable shared ownership code, because it is very easy for such code to be insecure memory (and memory safety is the main purpose of Rust) .

+1
source

All Articles