你如何像 itertools 那样用 collect_vec() 扩展特征?

How do you extend a trait like itertools does with collect_vec()?

我想创建一个类似于 itertools 中的 collect_vec() 函数的方法。

通过复制 itertools 代码创建一个小示例:

pub trait MyItertools: Iterator {
    fn collect_vec(self) -> Vec<Self::Item>
        where Self: Sized
    {
        self.collect()
    }
}

fn main() {
    let v = (0..5).collect_vec();
    println!("{:?}", v);
}

我天真地期望编译器会使用我的 collect_vec 作为 MyItertools 在范围内。

itertools 一定有一些其他的魔法来让它编译。

我们得到错误:

error[E0599]: no method named `collect_vec` found for struct `std::ops::Range<{integer}>` in the current scope
  --> src/main.rs:14:20
   |
14 |     let v = (0..5).collect_vec();
   |                    ^^^^^^^^^^^ method not found in `std::ops::Range<{integer}>`
   |
   = help: items from traits can only be used if the trait is implemented and in scope
note: `MyItertools` defines an item `collect_vec`, perhaps you need to implement it
  --> src/main.rs:5:1
   |
5  | pub trait MyItertools: Iterator {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

这是一种误导,因为我们确实在 MyItertools 中实施了 collect_vec

一个可能的解决方案是 impl MyItertools 用于所有口味 Iterator,但似乎没有办法对所有 Iterator 实现特征和类型执行此操作。

拼图中缺少的魔法部分是一个通用的整体实现,它为实现 Iterator 特性的所有类型实现 MyItertools 特性。更新固定示例:

pub trait MyItertools: Iterator {
    fn collect_vec(self) -> Vec<Self::Item>
        where Self: Sized
    {
        self.collect()
    }
}

impl<T> MyItertools for T where T: Iterator {}

fn main() {
    let v = (0..5).collect_vec();
    println!("{:?}", v);
}

playground