调用trait的关联函数时如何指定关联类型<Item=...>?

How to specify associated type <Item=...> when calling associated function of a trait?

我有这个 rust 代码 playground:

use itertools::{repeat_n,RepeatN};

pub trait MyIterator: Iterator {
    fn fill1(elem: Self::Item, n1: usize) -> RepeatN<Self::Item>
    where
        Self::Item: Clone,
    {
        repeat_n(elem, n1)
    }
}

我的问题是我无法调用此方法,因为 rustc 无法推断类型。

// error[E0284]: type annotations needed
// let r: RepeatN<char> = MyIterator::fill1('a', 5);
//                        ^^^^^^^^^^^^^^^^^ cannot infer type
// note: cannot satisfy `<_ as Iterator>::Item == _`
let r: RepeatN<char> = MyIterator::fill1('a', 5);

我试过了,但没有编译:

// error[E0229]: associated type bindings are not allowed here
let r: RepeatN<char> = MyIterator::<Item=char>::fill1('a', 5);

如何在这个调用中指定Item的类型?还是特征之外的函数(如 itertools::repeat_n)是这里最好的方法?

好吧,您还没有为任何类型实现特征,因此实际上不存在 fill1 函数。

如果您为实现 Iterator<Item = char> 的某种类型实现 MyIterator,例如 std::iter::Empty<char>,那么您将能够通过该类型调用 fill1

use std::iter::Empty;
impl MyIterator for Empty<char> {}

fn main() {
    let r: RepeatN<char> = Empty::fill1('a', 5);
}

然而,这是毫无意义的。您会注意到 Empty 在实际的函数定义中没有任何作用——它可能是任何迭代器。此外,没有将此行为合理地推广到其他 Self 类型。这就是为什么 itertools::repeat_n 不是 Itertools 特征的成员:它作为特征函数是无意义的,因为它不是多个迭代器类型共享的行为的概括。

在 Rust 中,与其他一些语言不同,并不是所有的东西都必须是 class 的成员。如果你只是想把fill1和相关的东西放在一个普通的namespace里,那么就用模块吧,模块是最基本的代码组织单位

mod my_iterator {
    use itertools::{repeat_n, RepeatN};

    fn fill1<T>(elem: T, n1: usize) -> RepeatN<T>
    where
        T: Clone,
    {
        repeat_n(elem, n1)
    }
}