如何使用conservative_impl_trait返回对迭代器的引用?

时间:2018-03-10 18:42:58

标签: rust

我有一个Capybara.default_max_wait_time = 6 # This just needs to be longer (in seconds) than however long the selects take to get their new entries find('a#filterBrand-button').click find(:select, 'filterBranch').all(:option, text: /^((?!-- Select --).)*$/, minimum: 1).each do |option| puts option.text option.select_option find('a#filterModel-button').click find(:select, 'filterModel').all(:option, text: /^((?!-- Select --).)*$/, minimum: 1).each do |option2| puts option2.text option2.select_option find('a#filterVersion-button').click find(:select, 'filterVersion').all(:option, text: /^((?!-- Select --).)*$/, minimum: 1).each do |option3| option3.select_option puts option3.text end end end 结构,我通过给每个节点权重petgraph::Graph强加一个树结构,parent_edge_idx是从其父节点到它自己的边缘的Option<EdgeIdx>

我需要遍历节点的子节点。我需要连接边缘的边缘权重孩子的节点权重。

我想将迭代分解为一个辅助函数,该函数返回对Iterator<Item = (EdgeIdx, NodeIdx)>的引用。我想这样做是免费的;因为我必须借用self.search_tree来执行此操作,所以迭代器仅在self的生命周期内有效。

  1. 这是一个想写的合理功能吗?
  2. 是否可以编写此功能?
  3. 任何门控功能都可以;我每晚都在。

    fn children<'a>(
        &'a mut self,
        node_idx: NodeIdx,
    ) -> &'a impl Iterator<Item = (EdgeIdx, NodeIdx)> {
        &self.search_tree.neighbors(node_idx).map(|child_idx| {
            let node = self.search_tree.node_weight(child_idx).unwrap();
            let edge_idx = node.parent_edge_idx.unwrap();
            (edge_idx, child_idx)
        })
    }
    

1 个答案:

答案 0 :(得分:4)

如何返回迭代器已经涵盖in this question

  1. 请注意,您don't need to return a reference:您希望直接返回迭代器,因此如果我们删除方法体和返回中的第一个&类型,它更接近我们需要的。

  2. 我们将使用impl Iterator,因此我们不必完全命名实际的迭代器类型。请注意(下面的代码)我们need to use the impl Iterator<..> + 'a syntax,这意味着(匿名)迭代器包含有效使用至少生命周期'a的引用。

  3. 我们不能在这里使用&mut self!请注意,我们需要两次借用self.search_tree:一次用于.neighbors()迭代器,一次用于self.search_tree一次用于 map闭合。多次借用与可变引用不兼容。

  4. 我们将move作为捕获模式放在闭包上,以便它直接捕获self引用,而不是通过引用(这很重要,这样我们就可以返回迭代器和关闭。

  5. Petgraph具体,但我们将g.node_weight(node_index).unwrap()替换为仅相当的&g[node_index],但后者更易于阅读。

  6. 这是您的代码的再现,但是随着1-5的修改使其编译:

    #![feature(conservative_impl_trait)]
    extern crate petgraph;
    
    use petgraph::Graph;
    use petgraph::graph::{NodeIndex, EdgeIndex};
    
    struct Foo {
        search_tree: Graph<Node, i32>,
    }
    
    struct Node {
        parent_edge_idx: Option<EdgeIndex>,
    }
    
    impl Foo {
        fn children<'a>(&'a self, node_idx: NodeIndex)
            -> impl Iterator<Item = (EdgeIndex, NodeIndex)> + 'a
        {
            self.search_tree.neighbors(node_idx).map(move |child_idx| {
                let node = &self.search_tree[child_idx];
                let edge_idx = node.parent_edge_idx.unwrap();
                (edge_idx, child_idx)
            })
        }
    }