Rust 如何编写返回迭代器的trait?

Rust 如何编写返回迭代器的trait?,rust,Rust,大体而言,我的目标是: 对于一些已知的类型栏 有一个trait Foo和一个函数:get_iterator()->T其中T:iterator 迭代器的实例借用了Foo在上实现的原始对象 我想象它是这样工作的: let mut foo = Foo; let bar = foo.get_iterator(); foo.mutable_call(); // <-- This fails, because foo is borrowed in bar for x in bar { .

大体而言,我的目标是:

  • 对于一些已知的类型栏
  • 有一个trait Foo和一个函数:
    get_iterator()->T其中T:iterator
  • 迭代器的实例借用了Foo在上实现的原始对象
我想象它是这样工作的:

let mut foo = Foo;
let bar = foo.get_iterator();

foo.mutable_call(); // <-- This fails, because foo is borrowed in bar

for x in bar { 
  ...
}
trait HasValsIterator {
    type Iter<'a>: Iterator<Item=Val> + 'a
    fn val_iterator<'a>(&'a self) -> Iter<'a>;
}

有什么办法可以做到这一点吗?

不幸的是,Veedrac的建议没有直接起作用。如果尝试在
实例
内部
获取vals()
上使用
val\u迭代器()
方法,将出现以下错误:

:31:25:31:39错误:没有为类型'U`[E0277]实现特性'core::iter::Iterator'
:31让iter=instance.val_迭代器();
^~~~~~~~~~~~~~
:31:25:31:39帮助:请参阅E0277的详细说明
:31:25:31:39注意:'U'不是迭代器;也许可以尝试调用“.iter()”或类似的方法
错误:由于上一个错误而中止
playpen:应用程序终止,错误代码为101
这(以及其他一些错误)需要将函数的签名更改为:

fn takes_vals<'a, T: 'a, U: Iterator<Item=Val>+'a>(instance: T) where T: HasValsIterator<'a, U>
这很有效

我想补充一点,使用关联类型而不是类型参数在语义上更为正确:

trait HasValsIterator<'a> {
    type Iter: Iterator<Item=Val> + 'a;
    fn val_iterator(&'a self) -> Self::Iter;
}

impl<'a> HasValsIterator<'a> for Foo {
    type Iter = ValsFromT<'a, Foo>;
    fn val_iterator(&'a self) -> ValsFromT<'a, Foo> { ... }
}

fn takes_vals<'a, T: 'a>(instance: &'a T) where T: HasValsIterator<'a> {
    ...
}

这样,
val_iterator()
在任何情况下都可以使用,包括
HasValsIterator
implementor按值传递时。然而,锈还没有出现。

不幸的是,Veedrac的建议没有直接起作用。如果尝试在
实例
内部
获取vals()
上使用
val\u迭代器()
方法,将出现以下错误:

:31:25:31:39错误:没有为类型'U`[E0277]实现特性'core::iter::Iterator'
:31让iter=instance.val_迭代器();
^~~~~~~~~~~~~~
:31:25:31:39帮助:请参阅E0277的详细说明
:31:25:31:39注意:'U'不是迭代器;也许可以尝试调用“.iter()”或类似的方法
错误:由于上一个错误而中止
playpen:应用程序终止,错误代码为101
这(以及其他一些错误)需要将函数的签名更改为:

fn takes_vals<'a, T: 'a, U: Iterator<Item=Val>+'a>(instance: T) where T: HasValsIterator<'a, U>
这很有效

我想补充一点,使用关联类型而不是类型参数在语义上更为正确:

trait HasValsIterator<'a> {
    type Iter: Iterator<Item=Val> + 'a;
    fn val_iterator(&'a self) -> Self::Iter;
}

impl<'a> HasValsIterator<'a> for Foo {
    type Iter = ValsFromT<'a, Foo>;
    fn val_iterator(&'a self) -> ValsFromT<'a, Foo> { ... }
}

fn takes_vals<'a, T: 'a>(instance: &'a T) where T: HasValsIterator<'a> {
    ...
}

这样,
val_iterator()
在任何情况下都可以使用,包括
HasValsIterator
implementor按值传递时。然而,锈迹还没有出现。

?@Veedrac哦,这只是语义学上的问题,实际上并不是借用自我的问题。如果你想把它变成一个答案,我会接受的~?@Veedrac哦,这只是语义学,实际上不是借用self的问题。如果你想把它变成一个答案,我会接受的~
trait HasValsIterator {
    type Iter<'a>: Iterator<Item=Val> + 'a
    fn val_iterator<'a>(&'a self) -> Iter<'a>;
}