In my code I have a mutually recursive tree structure which looks something like the following:
enum Child<'r> {
A(&'r Node<'r>),
B,
C
}
struct Node<'r> {
children : [&'r Child<'r>,..25]
}
impl <'r>Node<'r> {
fn new() -> Node {
Node {
children : [&B,..25]
}
}
}
but it doesn't compile as-is. What is the best way to modify it to make it do so?
Here is a version where the nodes can be modified from outside the tree, which I presume is what was asked for.
Rc
is a reference counted pointer and allows a single object to have multiple owners. It doesn't allow mutation however, so aRefCell
is required which allows runtime checked mutable borrowing. That's why the code usesRc<RefCell<Node>>
. The Option type is used to represent potential children withOption<Rc<RefCell<Node>>>
.Since, the Rc type auto dereferences, it's possible to directly call RefCell methods on it. These are
borrow()
andborrow_mut()
which return a reference and mutable reference to the underlying Node. There also existtry_borrow()
andtry_borrow_mut()
variants which cannot fail.get_ref()
is a method of the Option type which returns a reference to the underlyingRc<RefCell<Node>>
. In a real peogram we would probably want to check whether the Option contains anything beforehand.Why does the original code not work? References
&T
imply non-ownership, so something else would have to own the Nodes. While it would be possible to build a tree of&Node
types, it wouldn't be possible to modify the Nodes outside of the tree because once borrowed, an object cannot be modified by anything else than the borrowing object.