Recursion 在Rust中生成具有递归函数的树结构时的多个可变借用

Recursion 在Rust中生成具有递归函数的树结构时的多个可变借用,recursion,rust,Recursion,Rust,我在实现一个递归函数时遇到了问题,该函数通过操作一个可变的索引列表来生成一个二叉树,该列表将索引转换为一个不可变的列表 代码如下: enum Tree<'r, T:'r> {

我在实现一个递归函数时遇到了问题,该函数通过操作一个可变的索引列表来生成一个二叉树,该列表将索引转换为一个不可变的列表

代码如下:

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)
}
enum树{
节点(框>{
设n=xs.len();
如果n==0{返回框为空;}
过程要素(指标);
设pivot_指数=n/2;
设左_子树=
//借1~~~v
构建_树(xs,index.slice_to_或_fail_mut(&pivot_index));
让右子树=
//借2~~~v
构建_树(xs,index.slice_from_或_fail_mut(&(pivot_index+1)));
长方体节点(左_子树,&xs[pivot_index],右_子树)
}
当我试图编译它时,我得到一个错误,说我不能一次多次将
*索引
作为可变索引进行借用,第一次借用发生在标记为
借用1
的注释处,第二次借用发生在
借用2

我清楚地看到,
*点
确实在这两个位置都被借用,但在我看来,
*点
的第一次借用应该只持续到
let left_subtree
语句中对
build_tree
的一次递归调用结束l整个
构建树
函数的结尾

请任何人解释一下:

  • 为什么第一次借用会持续到
    构建树
    函数结束,以及
  • 如何在Rust中正确实现这样的功能

  • 顺便说一句:如果我删除“let left_subtree=”和“let right_subtree=”(即,使用递归调用
    build_tree
    ,仅用于它们对
    索引的副作用,并将
    None
    s传递给
    节点
    构造函数),代码编译得很好,没有抱怨多次借用。这是为什么?

    构建树的结果是
    Box>{
    设n=xs.len();
    如果n==0{返回框为空;}
    过程要素(指标);
    设pivot_指数=n/2;
    let(左指数,右指数)=指数。在多个(轴指数)处分割指数;
    let(u,index_right)=index_right.split_at_mut(1);
    让左_子树=构建_树(xs,索引_左);
    设right_subtree=build_tree(xs,index_right);
    长方体节点(左_子树,&xs[pivot_index],右_子树)
    }
    
    哦,你说得对极了!我甚至从未打算在索引中添加生存期参数。谢谢!!
    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 (indices_left, indices_right) = indices.split_at_mut(pivot_index);
        let (_, indices_right) = indices_right.split_at_mut(1);
        let left_subtree = build_tree(xs, indices_left);
        let right_subtree = build_tree(xs, indices_right);
        box Node(left_subtree, &xs[pivot_index], right_subtree)
    }