从函数返回递归迭代器

时间:2017-03-10 14:57:49

标签: rust

我有一个returns a flat-mapped Vec over children of a tree

的功能
use std::iter;

#[derive(Clone)]
struct Tree {
    value: String,
    children: Vec<Tree>,
}

struct NoClone;

impl NoClone {
    pub fn children(&self, from: &Tree) -> Vec<Tree> {
        from.children.clone()
    }

    pub fn descendants_vec<'a>(&'a self, from: Tree) -> Vec<Tree> {
        let children = self.children(&from);
        iter::once(from)
            .chain(children.into_iter().flat_map(|child| self.descendants_vec(child)))
            .collect::<Vec<Tree>>()
    }

    pub fn descendants_iter<'a>(&'a self, from: Tree) -> Box<Iterator<Item = Tree> + 'a> {
        let children = self.children(&from);
        Box::new(iter::once(from)
                     .chain(children.into_iter().flat_map(move |child| {
                                                              self.descendants_iter(child)
                                                          })))
    }
}

fn main() {
    //println!("Flattened (Iter): {:?}", mapped_iter());
    println!("Flattened (Vec): {:?}", mapped_vec());
}

fn tree() -> Tree {
    let tree_a = Tree {
        value: "a".to_owned(),
        children: Vec::new(),
    };

    let tree_b = Tree {
        value: "b".to_owned(),
        children: Vec::new(),
    };

    let tree_c = Tree {
        value: "c".to_owned(),
        children: Vec::new(),
    };

    Tree {
        value: "abc".to_owned(),
        children: vec![tree_a, tree_b, tree_c],
    }
}

/*fn mapped_iter() -> Vec<String> {
    let tree = tree();
    let no_clone = NoClone;
    no_clone.descendants_iter(tree).map(|x| x.value).collect::<Vec<String>>()
}*/

fn mapped_vec() -> Vec<String> {
    let tree = tree();
    let no_clone = NoClone;
    no_clone.descendants_vec(tree)
        .into_iter()
        .map(|x| x.value)
        .collect::<Vec<String>>()
}

我想避免使用中间collect / iter并使用descendants_iter返回Iterator(装箱直到我们获得impl特征)。

但是,取消注释调用此函数的块会导致编译器抱怨以下错误:

error: `no_clone` does not live long enough
  --> <anon>:63:1
   |
62 |     no_clone.descendants_iter(tree).map(|x| x.value).collect::<Vec<String>>()
   |     -------- borrow occurs here
63 | }
   | ^ `no_clone` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

error: aborting due to previous error

有关如何使用descendants_iter功能的任何想法?

0 个答案:

没有答案