我正在使用Rust中的AST,我认为如果所有节点都能简单地将切片包含到原始源字符串中,而不是复制内存的话,这将是一件很好的事情。但是,我无法确定如何在代码中构建生命周期,以便实现这一目标。我天真的尝试产生了这个程序:
#[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);
}
编译器输出:
error[E0502]: cannot borrow `tree` as immutable because it is also borrowed as mutable
--> ast.rs:32:22
|
31 | tree.slice(2, 6);
| ---- mutable borrow occurs here
32 | println!("{:?}", tree);
| ^^^^ immutable borrow occurs here
33 | }
| - mutable borrow ends here
这没有编译,因为:
slice()
函数调用的生存期。self
获取的对slice()
的可变引用需要超过slice()
函数调用。tree
函数中的tree.slice()
调用之后,main
仍然是不断借用的。println!
宏无法编译。理想情况下,节点中的切片需要能够超过slice()
调用,但是可变引用self
不应该存在。我了解到,借用检查器禁止这样做,因为self
包含片引用的source
字符串。
考虑到这一点,我如何重构代码以允许节点包含到源代码中,而不必借用self
的时间超过slice
函数的长度?这是可行的,还是需要我求助于unsafe
?
发布于 2018-03-20 13:11:52
解决问题的最简单方法是存储std::ops::Range<usize>
而不是&str
。然后,当您需要查看实际字符串时,在AST上提供一个接受Range<usize>
并返回&str
的方法。
另一种方法是不拥有原始字符串,而是将AST绑定到解析字符串的生存期,例如,
#[derive(Debug)]
struct Tree<'source> {
source: &'source str,
nodes : Vec<Node<'source>>,
}
你不能这样做,你有它的设置,因为锈不知道如何检查兄弟借款。如果你在搜索兄弟姐妹的借款问题,你会得到更多的上下文。
https://stackoverflow.com/questions/49393139
复制相似问题