性状与寿命由一个参数的寿命有界返回迭代
我有一个特点它说的Foo
任何实施需要提供一种方法bar
它返回某种类型的,它实现Iterator<Item = u32>
的目的:性状与寿命由一个参数的寿命有界返回迭代
trait Foo {
type FooIterator: Iterator<Item = u32>;
fn bar(&self) -> FooIterator;
}
对于这种情况,我相信默认的生存期限elision意味着由bar
返回的迭代器需要独立生存,而不必受限于它正在迭代的Foo
的生命周期。 #rust irc上的用户Habnabit建议以下方式说明FooIterator
的使用期限低于Foo
的使用期限。也就是说,它允许FooIterator
的执行,以保持到它来自Foo
参考:
trait Foo<'a> {
type FooIterator: Iterator<Item = u32> + 'a;
fn bar<'b: 'a>(&'b self) -> Self::FooIterator;
}
我真正想要的是函数bar
需要一个额外的参数的情况下,和FooIterator
实现被允许以保留对Foo
和附加参数的引用。即FooIterator
的生存期由Foo
的生存期和附加参数的生存期限定。
我这种想法的直译是
trait Zip {}
trait Foo<'a, 'c> {
type FooIterator: Iterator<Item = u32> + 'a + 'c;
// Foo.bar() returns an iterator that has a lifetime less than the Foo
fn bar<'b: 'a, 'd: 'c>(&'b self, &'d Zip) -> Self::FooIterator;
}
但有人告诉我,有没有“好”的方式做到这一点。实施这个习语最好的方法是什么?上面的代码会做什么?
您要找的是associated type constructors,这是一个尚未在Rust中实施的计划功能。随着相关类型构造器,你的代码应该是这样的:
trait Zip {}
trait Foo {
type FooIterator<'a, 'c>: Iterator<Item = u32> + 'a + 'c;
// Foo.bar() returns an iterator that has a lifetime less than the Foo
fn bar<'a, 'b: 'a, 'c, 'd: 'c>(&'b self, &'d Zip) -> Self::FooIterator<'a, 'c>;
}
其实,我不知道那些寿命是必要的,因为&'a T
可强制转换为&'b T
其中'a: 'b
。因此,下面可能是不够好:
trait Zip {}
trait Foo {
type FooIterator<'a, 'c>: Iterator<Item = u32> + 'a + 'c;
// Foo.bar() returns an iterator that has a lifetime less than the Foo
fn bar<'a, 'c>(&'a self, &'c Zip) -> Self::FooIterator<'a, 'c>;
}
根据您想如何使用这个特质,你可以让它通过实现它&'a Struct
,而不是为Struct
,从而“提升”责任工作寻找从特质到呼叫者的正确生活。
从性状取出寿命注释和改变bar
所以需要self
,加上相同的寿命的另一种说法:
trait Foo {
type FooIterator: Iterator<Item = u32>;
fn bar(self, other: Self) -> Self::FooIterator;
}
(从性状卸下'a
是可能的,因为bar
消耗基准代替reborrowing的它 - self
因为它已经被移入它,所以不必再有返回值了。)
然后impl
它为终生的参考'a
:
impl<'a> Foo for &'a Vec<u32> {
type FooIterator = ...; // something presumably containing 'a
fn bar(self, other: Self) -> Self::FooIterator {
...
}
}
这工作,因为编译器寿命'a
限制在一个为其IMPL适用。
Here's a playground link其中bar
基本上是围绕.chain()
的包装。
现在我忽略了Zip
这个特性,因为如何合并它取决于它提供了什么。相反,我想bar
只接受与Self
相同类型的参数。然而,你也可以添加它,如果你需要的话也许使用相同的技术。
每当我问一个Rust问题时,你都必须有一个提示:)有趣的,但它似乎不像关联类型的构造函数将很快在Rust中。解决方法是什么? –
我在看着https://*.com/questions/tagged/rust,我并不孤单。 ;)据我所知,没有解决方法,这就是为什么这个功能正在开发过程中。 –