简体   繁体   English

如何使用 Rust 在树结构中为单个节点提供多个引用

[英]How to have multiple references for a single node in a tree structure using Rust

Trying to create a tree in rust with the following struct:尝试使用以下结构在 rust 中创建树:

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:要构建一个新节点,请使用以下 function:

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 .会有错误,因为我正在借用例如root_nd然后尝试将next_nd添加到root.children列表中,即使没有这个错误,我仍然需要在将next_nd添加到root_nd的孩子之后有一个参考. I know that in rust it is not possible to have several mutable references simultaneously for the same element.我知道在 rust 中,同一元素不可能同时有多个可变引用。 So the question is how is it possible to make a tree-like data structure, with bi-directional references in rust?所以问题是如何在 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.在我看来,这是一个冲突,因为 rust 不想要多个引用,但我需要树中间的一个节点供他的父节点和他的子节点引用。

I've been meddling with trees in Rust for quite a bit recently.最近我一直在干预 Rust 中的树木。 To work with trees in rust, you will need Rc (A single-threaded reference-counting pointer) so that you can have multiple ownership.要使用 rust 中的树,您将需要Rc (单线程引用计数指针) ,以便您可以拥有多个所有权。 And you'll also need RefCell to enable interior mutability since multiple mutable references are not allowed by the compiler.而且您还需要RefCell来启用内部可变性,因为编译器不允许多个可变引用。 With Rc and RefCell , you can define your TreeNode as following:使用RcRefCell ,您可以将TreeNode定义如下:

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.由于我们使用Rc::clone来创建对节点的新引用,因此root_ndchild_nd不会被消耗,并且仍然可以在以后的程序中访问。

More examples on Trees in Rust: Rust 中的树的更多示例:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM