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