简体   繁体   English

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

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

I would like to create a method similar to the collect_vec() function in itertools .我想在itertools中创建一个类似于collect_vec() function 的方法。

Creating a small example by copying the itertools code:通过复制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);
}

I rather naively expect that the compiler will use my collect_vec as MyItertools is in scope.我相当天真地期望编译器将使用我的collect_vec ,因为MyItertools在 scope 中。

There must be some other magic that itertools is doing to get this to compile. itertools一定有一些其他的魔法来让它编译。

We get the error:我们得到错误:

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

Which is misleading as we have indeed implemented collect_vec in MyItertools .这是误导性的,因为我们确实在MyItertools collect_vec

One possible solution is to impl MyItertools for all flavours of Iterator , but there does not seem to be a way to do this for all Iterator implementing traits and types.一种可能的解决方案是为所有类型的Iterator impl MyItertools ,但似乎没有办法对所有实现特征和类型的Iterator执行此操作。

The missing magic piece of the puzzle is a generic blanket implementation that implements the MyItertools trait for all types which implement the Iterator trait.这个谜题中缺少的魔法部分是一个通用的整体实现,它为所有实现Iterator特性的类型实现了MyItertools特性。 Updated fixed example:更新固定示例:

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 操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM