一些算法通过递归地将数组划分为较小的部分。你可以构建一个明确的二叉树,该树来自这样的过程,其中每个叶子节点都保存数组的不相交片段。如果需要更改或重新排序叶子中的元素,则必须使其片段可变。
enum Tree<'a> {
Branch(Box<[Tree<'a>; 2]>),
Leaf(&'a mut[f32]),
}
假设我需要分割所有大于某个阈值的叶子节点。很简单:从根节点开始递归地遍历整棵树;当我找到一个足够长的叶子节点时,将其分成两半,将它们包装成一个有两个叶子节点的子树,并替换原来的叶子节点。
impl<'a> Tree<'a> {
fn split(&mut self, max: usize) {
match self {
&mut Tree::Branch(ref mut trees) => {
trees[0].split(max);
trees[1].split(max);
},
&mut Tree::Leaf(ref mut leaf) if leaf.len() > max => {
let mid = leaf.len() / 2;
let (l, r) = leaf.split_at_mut(mid);
let trees = [Tree::Leaf(l), Tree::Leaf(r)];
*self = Tree::Branch(Box::new(trees));
},
}
}
}
很遗憾,借用检查器无法为ref mut leaf
模式找到合适的生命周期。它想在允许对*self
进行赋值之前将其销毁,但我不知道如何使匹配分支外的赋值生效。
如何解决这个问题?