Rust 如何构造树结构,其中节点包含对包含树结构的字段的引用
我正在Rust中使用AST,我认为最好的一件事是,如果所有节点都可以简单地将片段包含到原始源字符串中,而不是复制周围的内存。然而,我不太清楚应该如何在代码中构建生命周期,以实现这个目标。我天真的尝试产生了这个程序:Rust 如何构造树结构,其中节点包含对包含树结构的字段的引用,rust,Rust,我正在Rust中使用AST,我认为最好的一件事是,如果所有节点都可以简单地将片段包含到原始源字符串中,而不是复制周围的内存。然而,我不太清楚应该如何在代码中构建生命周期,以实现这个目标。我天真的尝试产生了这个程序: #[derive(Debug)] struct Node<'source> { slice : &'source str, nid : usize , parent : usize , chil
#[derive(Debug)]
struct Node<'source> {
slice : &'source str,
nid : usize ,
parent : usize ,
children: Vec<usize> ,
}
#[derive(Debug)]
struct Tree<'source> {
source: String ,
nodes : Vec<Node<'source>>,
}
impl<'source> Tree<'source> {
fn new() -> Self {
Tree {source: String::from("Hello World"), nodes: vec![]}
}
fn slice(&'source mut self, from: usize, to: usize) {
let new_nid = self.nodes.len();
self.nodes.push(
Node { slice: &self.source[from..to], nid: new_nid, parent: 0, children: vec![] }
);
}
}
fn main() {
let mut tree = Tree::new();
tree.slice(2, 6);
println!("{:?}", tree);
}
这不会编译,因为:
- 节点包含的切片需要比
函数调用更有效slice()
- 因此,
对slice()
的可变引用需要比self
函数调用更有效slice()
- 因此,在调用
函数中的main
之后,tree.slice()
仍然是可变借用的tree
- 因此,
println代码>宏无法编译
slice()
调用更长寿,但可变引用self
不应该。我知道借阅检查器禁止这样做,因为self
包含source
字符串,切片引用到该字符串中
考虑到这一点,我如何重新构造代码以允许节点将切片包含到源代码中,而不必借用
self
的长度超过slice
函数的长度?这是否可行,或者我需要求助于不安全的?解决问题的最简单方法是存储std::ops::Range
,而不是&str
。然后,当需要查看实际字符串时,在AST上提供一个方法,该方法接受范围
,并返回&str
另一种方法是不拥有原始字符串,而是将AST与解析它的字符串的生存期绑定,例如
#[derive(Debug)]
struct Tree<'source> {
source: &'source str,
nodes : Vec<Node<'source>>,
}
#[派生(调试)]
如果所有节点都可以简单地将片段包含到原始源字符串中,那么struct tree将是一种非常有效的解析技术(我在几乎所有的解析器中都使用了这种技术),但您的代码并不是这样做的。