寻找有关在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鼠游戏中。
答案 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
,但是我认为这样做会很麻烦,因为此迭代器必须以某种方式跟踪当前状态(也许可以证明我错了并表明实际上很容易做到)。