生锈的自我树箱:循环内带有可变借位的循环

时间:2019-05-22 22:48:25

标签: rust

我使用的是ego-tree板条箱的0.6.0版,我不确定如何遍历可变节点。以下是一个人为的示例,但它说明了我的意图。对于append(&mut self)操作,它也可以视为其他任何也可以引用可变功能的简单占位符。

基本问题是,鉴于每次请求新的同级项都会消耗可变引用,因此我不理解如何从概念上遍历同级节点。

我了解编译器告诉我,可变引用在使用后(在> =第2次迭代时)无法使用,但是我不知道该使用哪种模式。

我收到的错误是:

error[E0597]: `sibling` does not live long enough
  --> src/main.rs:15:35
   |
12 |             while !sibling_mut.is_none() {
   |                    ----------- borrow used here, in later iteration of loop
...
15 |                     sibling_mut = sibling.next_sibling();
   |                                   ^^^^^^^ borrowed value does not live long enough
16 |                 }
   |                 - `sibling` dropped here while still borrowed

重现该错误的代码:

use ego_tree::{tree, NodeMut, Tree};

/// Traverse the tree and insert a sibling after the node specified by `data`
fn traverse(node: &mut Option<NodeMut<String>>) {
    match node {
        None => {
            println!("done traversing a level");
            return;
        }
        Some(n) => {
            let mut sibling_mut = n.next_sibling();
            while !sibling_mut.is_none() {
                if let Some(mut sibling) = sibling_mut {
                    sibling.append("x".into());
                    sibling_mut = sibling.next_sibling();
                }
            }
            traverse(&mut None);
        }
    }
}

fn main() {
    let mut tree = build_simple_tree();
    traverse(&mut Some(tree.root_mut()));
}

fn build_simple_tree() -> Tree<String> {
    tree! {
        "a".into() => {
            "b".into(),
            "c".into(),
            "d".into(),
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您可以通过使用堆栈来做到这一点:

/// Traverse the tree and insert a sibling after the node specified by `data`
fn traverse(node: Option<NodeMut<String>>) {
    match node {
        None => {
            println!("done traversing a level");
            return;
        }
        Some(mut n) => {
            traverse(n.first_child());
            n.append("x".into());
            traverse(n.next_sibling());
        }
    }
}

使用:

fn main() {
    let mut tree = build_simple_tree();
    println!("{:#?}", tree);
    traverse(Some(tree.root_mut()));
    println!("{:#?}", tree);
}

这将输出:

Tree { "a" => { "b", "c", "d" } }
done traversing a level
done traversing a level
done traversing a level
done traversing a level
done traversing a level
Tree { "a" => { "b" => { "x" }, "c" => { "x" }, "d" => { "x" }, "x" } }