展平嵌套结构

时间:2018-11-25 13:20:02

标签: rust

寻找有关在Rust中修复借阅检查器/生命周期问题的智慧。我正在尝试将通用的嵌套结构(扁平化为impl迭代器或Vec)。可能要花上几秒钟才能完成工作:

fn iter_els(prev_result: Vec<&El>) -> Vec<&El> {
    // Iterate over all elements from a tree, starting at the top-level element.
    let mut result = prev_result.clone();

    for el in prev_result {
        for child in &el.children {
            result.push(&child.clone());
        }
        result.extend(iter_els(&el.children));
    }
    result
}

您会注意到,这引发的直接异常是iter_els期望引用的Vec,而不是引用本身。当直接解决此问题时,其他问题会调皮捣蛋,例如在氧化但安全的but鼠游戏中。

Playground

1 个答案:

答案 0 :(得分:1)

此任务有多种解决方案。一种是将结果作为输出参数传递给函数:

fn iter_els<'el>(el_top: &'el El, result: &mut Vec<&'el El>) {
    result.push(el_top);
    for el in &el_top.children {
        iter_els(el, result);
    }
}

fn main() {
    // build top_el as you did
    let mut result = Vec::new();
    iter_els(&top_el, &mut result);
    println!("{:?}", result);
}

采用您的原始方法恕我直言,会导致更复杂的实现:

fn iter_els<'el>(prev_result: &Vec<&'el El>) -> Vec<&'el El> {
    // Iterate over all elements from a tree, starting at the top-level element.
    let mut result = prev_result.clone();

    for el in prev_result {
        for child in &el.children {
            result.push(&child);
        }
        result.extend(iter_els(&el.children.iter().collect()));
    }
    result
}

fn main() {
    // build top_el as you did
    println!("{:?}", iter_els(&vec![&top_el]));
}

或者:

fn iter_els<'el>(prev_result: &'el Vec<El>) -> Vec<&'el El> {
    // Iterate over all elements from a tree, starting at the top-level element.
    let mut result : Vec<_> = prev_result.iter().collect();

    for el in prev_result {
        for child in &el.children {
            result.push(child);
        }
        result.extend(iter_els(&el.children));
    }
    result
}

fn main() {
    // build top_el as you did
    println!("{:?}", iter_els(&vec![top_el]));
}

如您所见,第一种方法仅对不可变的El和一个单独的结果Vec起作用,而其他实现则无法解决clone和{{1} }。

理想情况下,您会为树写一个自定义collect,但是我认为这样做会很麻烦,因为此迭代器必须以某种方式跟踪当前状态(也许可以证明我错了并表明实际上很容易做到)。