Trying to create a tree in rust with the following struct:
pub struct Node{
pub children: Vec<Box<Node>>,
pub parent: Option<Box<Node>>,
pub value: f32,
//.....
}
To build a new node the following function is used:
pub fn build_node(parent: Option<Box<Node>>)-> Node{
Node{
children: vec![],
parent,
value: 0.0,
}
}
When trying to add nodes, for example with:
let mut root_nd = tree::build_node(None, 5, state);
let mut next_nd = tree::build_node(Some(Box::new(root_nd)), 2);
root_nd.children.push(Box::new(next_nd));
There will be errors, because I am borrowing for example root_nd
and then trying to add next_nd
to the root.children
list, and even if there wasnt this error I would still need to have a reference for next_nd
after adding it to the children of root_nd
. I know that in rust it is not possible to have several mutable references simultaneously for the same element. So the question is how is it possible to make a tree-like data structure, with bi-directional references in rust? In my head this is a conflict since rust does not want multiple references but I need a node in the middle of the tree to be referenced by both his parent node and his children nodes.
I've been meddling with trees in Rust for quite a bit recently. To work with trees in rust, you will need Rc
(A single-threaded reference-counting pointer) so that you can have multiple ownership. And you'll also need RefCell
to enable interior mutability since multiple mutable references are not allowed by the compiler. With Rc
and RefCell
, you can define your TreeNode as following:
use std::rc::Rc;
use std::cell::RefCell;
pub struct TreeNode {
pub children: Vec<Rc<RefCell<TreeNode>>>,
pub parent: Option<Rc<RefCell<TreeNode>>>,
pub value: f32,
}
And here is one way to create two nodes that references each other:
impl TreeNode {
#[inline]
pub fn new(value: f32) -> Self {
TreeNode {
value,
children: vec![],
parent: None
}
}
}
let mut root_nd = Rc::new(RefCell::new(TreeNode::new(5.0)));
let mut child_nd = Rc::new(RefCell::new(TreeNode::new(2.0)));
child_nd.borrow_mut().parent = Some(root_nd.clone()); // use Rc::clone to create a new reference to root_nd
root_nd.borrow_mut().children.push(child_nd.clone());
Since we use Rc::clone
to create a new reference to the node, root_nd
and child_nd
are not consumed and can still be accessed in later program.
More examples on Trees in Rust:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.