我试图在遍历树时构建树结构并维护路径。
这里有一些代码:
use std::collections::VecDeque;
struct Node {
children: VecDeque<Node>,
}
struct Cursor<'a> {
path: VecDeque<&'a mut Node>,
}
impl<'a> Cursor<'a> {
fn new(n: &mut Node) -> Cursor {
let mut v = VecDeque::new();
v.push_front(n);
Cursor { path: v }
}
fn go_down(&'a mut self, idx: usize) -> bool {
let n = match self.path[0].children.get_mut(idx) {
None => return false,
Some(x) => x
};
self.path.push_front(n);
true
}
}
我有两个问题。首先,编译器建议go_down()
self
参数中的生命周期说明符,但我不确定为什么它会修复报告的问题。
但是,即使进行了此更改,上述代码也无法编译,因为self.path
被借用了两次。有没有办法保持树节点的路径而不写'#34;不安全&#34;码?
答案 0 :(得分:1)
我最终遵循从this answer到Recursive Data Structures in Rust的方法。我们的想法是你使用拥有的对象而不是引用来操作,并在遍历它时解构和重构树。
这是我最终得到的代码:
use std::collections::VecDeque;
enum Child { Placeholder, Node(Node) }
struct Node {
children: Vec<Child>,
}
impl Node {
fn swap_child(&mut self, idx: usize, c: Child) -> Option<Child> {
match self.children.get(idx) {
None => None,
Some(_) => {
self.children.push(c);
Some(self.children.swap_remove(idx))
}
}
}
}
struct Cursor {
node: Node,
parents: VecDeque<(Node, usize /* index in parent */)>,
}
enum DescendRes { OK(Cursor), Fail(Cursor) }
enum AscendRes { Done(Node), Cursor(Cursor) }
impl Cursor {
fn new(n: Node) -> Cursor {
Cursor { node: n, parents: VecDeque::new() }
}
fn descent(mut self, idx: usize) -> DescendRes {
match self.node.swap_child(idx, Child::Placeholder) {
None => DescendRes::Fail(self),
Some(Child::Placeholder) => panic!("This should not happen"),
Some(Child::Node(child)) => {
let mut v = self.parents;
v.push_front((self.node, idx));
DescendRes::OK(
Cursor { node: child, parents: v }
)
}
}
}
fn ascend(mut self) -> AscendRes {
match self.parents.pop_front() {
None => AscendRes::Done(self.node),
Some((mut parent, parent_idx)) => {
match parent.swap_child(parent_idx, Child::Node(self.node)) {
Some(Child::Placeholder) => {
AscendRes::Cursor(
Cursor { node: parent, parents: self.parents }
)
},
_ => panic!("This should not happen")
}
}
}
}
}