我在实现一个递归函数时遇到问题,该函数通过操作索引到不可变列表的可变索引列表来生成二叉树。
这是代码:
enum Tree<'r, T:'r> {
Node(Box<Tree<'r, T>>,
&'r T,
Box<Tree<'r, T>>),
Empty
}
fn process_elements<T>(xs: &mut [T]) {
// interesting things happen here
}
// This function creates a tree of references to elements in a list 'xs' by
// generating a permutation 'indices' of a list of indices into 'xs',
// creating a tree node out of the center element, then recursively building
// the new node's left and right subtrees out of the elements to the left and
// right of the center element.
fn build_tree<'r, T>(xs: &'r [T],
indices: &'r mut [uint]) -> Box<Tree<'r, T>> {
let n = xs.len();
if n == 0 { return box Empty; }
process_elements(indices);
let pivot_index = n / 2;
let left_subtree =
// BORROW 1 ~~~v
build_tree(xs, indices.slice_to_or_fail_mut(&pivot_index));
let right_subtree =
// BORROW 2 ~~~v
build_tree(xs, indices.slice_from_or_fail_mut(&(pivot_index + 1)));
box Node(left_subtree, &xs[pivot_index], right_subtree)
}
当我尝试编译此文件时,出现错误,提示我无法借用*indices
一次多次可变,第一次借用发生在标记的注释处BORROW 1
第二次借用发生在BORROW 2
.
我清楚地看到*points
确实在这两个地点都借了,但在我看来,第一次借的*points
应该只持续到单个递归调用结束build_tree
in the let left_subtree
陈述。然而,Rust 声称这种借用实际上会持续到整个周期结束。build_tree
功能。
谁能解释一下:
- 为什么第一次借用会持续到最后
build_tree
函数,以及
- 像这样的函数如何在 Rust 中正确实现?
顺便说一句:如果我删除“let left_subtree =”和“let right_subtree =”(即,使用递归调用build_tree
只是因为它们的副作用indices
并通过None
到Node
构造函数),代码编译得很好并且不会抱怨多次借用。为什么是这样?