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

How do I return a reference to an iterator using conservative_impl_trait?

我有一个 petgraph::Graph 结构,我通过给每个节点权重一个 parent_edge_idx 来强加一个树结构,它是从它的 [= 连接的边缘的 Option<EdgeIdx> 37=] 到它自己。

我需要遍历节点的 children。我需要连接边的边权重 child.

的节点权重

我想将该迭代分解为一个 returns 对 Iterator<Item = (EdgeIdx, NodeIdx)> 的引用的辅助函数。我想这样做cost-free;由于我必须借用 self.search_tree 才能执行此操作,因此迭代器仅在 self.

的生命周期内有效
  1. 这是一个想写的合理函数吗?
  2. 这个函数可以写吗?

任何门控功能都可以;我在每晚。

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)
    })
}

如何 return 迭代器已经被覆盖 in this question

  1. 注意你 don't need to return a reference: 你想 return 一个迭代器 value 直接,所以如果我们删除第一个 & 在方法体和 return 类型中,这更接近我们需要的。

  2. 我们将使用 impl Iterator 这样我们就不必准确命名实际的迭代器类型。请注意(下面的代码)我们 ,这意味着(匿名)迭代器包含至少在生命周期 'a.

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

  5. 我们把move作为闭包的捕获模式,这样它就可以直接捕获self引用,而不是通过引用(这很重要,这样我们就可以return 迭代器和闭包。

  6. Petgraph 特定,但我们将 g.node_weight(node_index).unwrap() 替换为 &g[node_index],这是等效的,但后者更易于阅读。

这是您的代码的复制,但对 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)
        })
    }
}