I'm new to Rust, and as part of the learning process, I'm attempting to create a tree structure where each node has a vector of children and a reference to its parent. I want to create an addChild()
function to the node, which takes the value of the new node (i32
s for now), adds it to the child-list, and passes a reference to itself as a parent. Following Rust by Example's linked list example, I'm trying to reference the parent with a Box<>
. Since I'm both modifying the parent and passing a reference to it, I got stuck, as the borrow checker doesn't want me to dereference the &mut self
(see the code below).
From this I have two questions:
What is the correct way to keep a reference the parent in a tree structure? In C I would keep a simple pointer to the parent and some arbitrary collection for the children.
How are you supposed to both modify and pass a reference to an object in the same function in Rust?
Below is the full code for my enum and impl, with an additional test-function to modify self without passing it.
#[derive(Hash, Eq, PartialEq)]
enum Node {
Elem {
value: i32,
parent: Box<Node>,
children: Vec<Node>,
},
Nil,
}
impl Node {
fn new(value: i32, parent: Box<Node>) -> Node {
return Node::Elem {
value: value,
parent: parent,
children: Vec::new(),
};
}
// This function works fine
fn setValue(&mut self, v: i32) {
match self {
&mut Node::Elem { ref mut value, .. } => *value = v,
&mut Node::Nil => {}
}
}
fn addChild(&mut self, value: i32) {
match self {
&mut Node::Elem { ref mut children, .. } => {
(*children).push(Node::new(value, Box::new(*self)))
// Produces E0507 (Cannot move out of borrowed context)
}
&mut Node::Nil => println!("Failed to add children to empty node"),
}
}
}