我想遍历Rust中的递归数据结构,其中 遍历功能应该可以访问所有已经遍历的祖先。 我目前拥有的是这样的:
enum Tree<N> {
Node(N, Vec<Box<Tree<N>>>),
}
// delete children of nodes that have an equivalent ancestor
fn traverse<N>(ancestors: &mut Vec<N>, t: Tree<N>) -> Tree<N>
where
N: std::cmp::PartialEq + Clone
{
let Tree::Node(n, ts) = t;
if ancestors.contains(&n) {
Tree::Node(n, Vec::new())
}
else {
ancestors.push(n.clone()); // <------ TODO: ugly
let ts = ts.into_iter().map(|bt| Box::new(traverse(ancestors, *bt))).collect();
ancestors.pop(); // <------ TODO: ugly
Tree::Node(n, ts)
}
}
我对traverse
函数中记录祖先的方式不满意:
使用可变的Vec
意味着我必须记住pop()
之后的push()
。
此外,我需要clone()
每个节点。
编写traverse
函数的惯用方式是什么?是否可以在没有克隆约束的情况下编写它?
NB :
在Haskell中,我将使用List
而不是Vec
,这样我就可以这样写:
data Tree n =
Node n [Tree n]
treeTraverse :: Eq a => [a] -> Tree a -> Tree a
treeTraverse ancestors (Node n ts) =
if n `elem` ancestors
then Node n []
else Node n (map (treeTraverse (n:ancestors)) ts)