Rust 将特征的引用作为迭代器进行边界时的生存期冲突

Rust 将特征的引用作为迭代器进行边界时的生存期冲突,rust,Rust,我尝试在泛型图上实现一些图算法。为此,我定义了两个图形特征,它们将返回一个泛型特征(具有集合操作)SetGraph或一个用于迭代节点邻域IteratorGraph的InIterator pub特征邻域迭代器图 哪里 &'a Self::S:into迭代器, 赛尔夫:S:a, { S型; fn获取邻域(&'a self,索引:usize)->&'a self::S; } 因为通常可以在集合上迭代,所以我还为所有能够在集合上迭代的集合图实现了NeighboryIteratorGraph impl&

我尝试在泛型图上实现一些图算法。为此,我定义了两个图形特征,它们将返回一个泛型特征(具有集合操作)SetGraph或一个用于迭代节点邻域IteratorGraph的InIterator

pub特征邻域迭代器图
哪里
&'a Self::S:into迭代器,
赛尔夫:S:a,
{
S型;
fn获取邻域(&'a self,索引:usize)->&'a self::S;
}
因为通常可以在集合上迭代,所以我还为所有能够在集合上迭代的集合图实现了NeighboryIteratorGraph

impl<'a, G> NeighborhoodIteratorGraph<'a> for G
where
    G: SetGraph<'a>,
    &'a G::S: IntoIterator<Item = usize>,
{
    type IntoIter = &'a G::S;
    fn get_neighborhood_iterator(&'a self, index: usize) -> Self::IntoIter {
        self.get_neighborhood(index)
    }
}
impl for G
哪里
G:SetGraph Self::IntoIter{
self.get_邻域(索引)
}
}
我需要向NeighborrhoodIteratorGraph添加一个生存期,否则编译器会告诉我我的实现将有一个无限的生存期

但是,我很快在这些生命周期中遇到了问题,我得到了以下代码的错误:

struct Foo<'a, G: NeighborhoodIteratorGraph<'a>> {
    graph: G,
    //otherwise we get an error because 'a wouldn't be used
    _marker: std::marker::PhantomData<&'a G>,
}

impl<'a, G: NeighborhoodIteratorGraph<'a>> Foo<'a, G> {
    pub fn find_matching_for<I>(&mut self, nodes: I) -> bool
    where
        I: std::iter::IntoIterator<Item = usize>,
    {
        for node in self.graph.get_neighborhood_iterator(3) {}
        return true;
    }
}
struct Foo>{
图:G,
//否则我们会得到一个错误,因为“a”不会被使用
_marker:std::marker::PhantomData{
pub fn find_matching_for(&mut self,nodes:I)->bool
哪里
I:std::iter::IntoIterator,
{
对于self.graph.get_邻域_迭代器(3){
返回true;
}
}
错误[E0495]:由于需求冲突,无法推断自动引用的适当生存期

似乎PhantomData字段更像是一个黑客,我找不到一种方法来获得一个集合引用,它可以被看作是一个InIterator对象

这是问题的症结所在

完整错误消息:

错误[E0495]:由于需求冲突,无法推断自动引用的适当生存期
-->src/lib.rs:38:32
|
38 |对于self.graph.get_邻域_迭代器(3){
|                                ^^^^^^^^^^^^^^^^^^^^^^^^^
|
注意:首先,生命周期不能超过方法体上34:5定义的匿名生命周期#1。。。
-->src/lib.rs:34:5
|
34 |/pub fn查找匹配(&mut self,节点:I)->bool
35 | |在哪里
36 | I:std::iter::into迭代器,
| |_________________________________________________^
注意:…这样引用就不会超过借用的内容
-->src/lib.rs:38:21
|
38 |对于self.graph.get_邻域_迭代器(3){
|                     ^^^^^^^^^^
注意:但是,生存期必须对impl上33:6定义的生存期“a”有效。。。
-->src/lib.rs:33:6
|

33 | impl>Foo您需要的是一个解决缺少泛型关联类型的问题,这些类型目前非常不稳定

pub特征邻域迭代器图{
键入IntoIter Self::IntoIter(&'b Self,index:usize)->Self::IntoIter
哪里
赛尔夫::因托特:'b;
}
然后,我从
SetGraph
中删除了不必要的生存期注释:


pub trait setgraph为什么
get_neighborary
需要一个
&a self
,而
'a
是该trait的一个参数?前面的问题是
。老实说,我觉得我太粗心了,插入了太多
'a
。但是,从
get_neighborary
参数中删除
'a
,然后返回
esn无法更改错误。HRTB语法似乎让我几乎达到了目的,但实现的类型
IntoIter
仍然会导致错误,因为没有关联类型的HRTB(至少我找不到示例)。更新后的游乐场:()
struct Foo<'a, G: NeighborhoodIteratorGraph<'a>> {
    graph: G,
    //otherwise we get an error because 'a wouldn't be used
    _marker: std::marker::PhantomData<&'a G>,
}

impl<'a, G: NeighborhoodIteratorGraph<'a>> Foo<'a, G> {
    pub fn find_matching_for<I>(&mut self, nodes: I) -> bool
    where
        I: std::iter::IntoIterator<Item = usize>,
    {
        for node in self.graph.get_neighborhood_iterator(3) {}
        return true;
    }
}
impl<'a, G> NeighborhoodIteratorGraph for &'a G
where
    G: SetGraph<'a>,
    &'a G::S: IntoIterator<Item = usize>,
{
    type IntoIter = &'a G::S;
    fn get_neighborhood_iterator<'b>(&'b self, index: usize) -> Self::IntoIter
    where
        Self::IntoIter: 'b,
    {
        self.get_neighborhood(index)
    }
}