简体   繁体   English

Trait实现了Iterator,但是不能使用实现我的trait的结构作为Iterator

[英]Trait implements Iterator, but cannot use a struct implementing my trait as an Iterator

I have a trait and I want to say that if a struct implements this trait then it can also act as an Iterator . 我有一个特性,我想说,如果一个结构实现了这个特性,那么它也可以充当Iterator However I'm getting a compiler error when trying to use a struct as an iterator. 但是,当我尝试使用struct作为迭代器时,我遇到了编译器错误。

I am writing a library to read the same type of data from many different file formats. 我正在编写一个库来从许多不同的文件格式中读取相同类型的数据。 I want to create a generic "reader" trait, which will return the proper rust objects. 我想创建一个通用的“读者”特征,它将返回适当的生锈对象。 I want to say that each reader can operate as an Iterator, yielding that object. 我想说每个读者都可以作为迭代器运行,产生该对象。

Here's the code 这是代码

/// A generic trait for reading u32s
trait MyReader {
    fn get_next(&mut self) -> Option<u32>;
}

/// Which means we should be able to iterate over the reader, yielding u32s
impl Iterator for MyReader {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        self.get_next()
    }
}

/// Example of a 'reader'
struct MyVec {
    buffer: Vec<u32>,
}

/// This can act as a reader
impl MyReader for MyVec {
    fn get_next(&mut self) -> Option<u32> {
        self.buffer.pop()
    }
}

fn main() {
    // Create a reader
    let mut veccy = MyVec { buffer: vec![1, 2, 3, 4, 5] };

    // Doesn't work :(
    let res = veccy.next();
}

The compiler output: 编译器输出:

rustc 1.15.0 (10893a9a3 2017-01-19)
error: no method named `next` found for type `MyVec` in the current scope
  --> <anon>:31:21
   |
31 |     let res = veccy.next();
   |                     ^^^^
   |
   = help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `next`, perhaps you need to implement one of them:
   = help: candidate #1: `std::iter::Iterator`
   = help: candidate #2: `std::iter::ZipImpl`
   = help: candidate #3: `std::str::pattern::Searcher`

Here is the code on the rust playground. 是生锈操场上的代码。

In my mind, since MyVec implements MyReader , then it should be usable as an iterator, and hence I should be able to call .next() on it. 在我看来,既然MyVec实现了MyReader ,那么它应该可以作为迭代器使用,因此我应该可以在它上面调用.next() Since I have implemented MyReader , then I should get an implementation for Iterator for free, right? 由于我已经实现了MyReader ,那么我应该免费获得Iterator的实现,对吧? The line impl Iterator for ... shows that Iterator is in scope, so I can't understand where the error comes from. impl Iterator for ...表明Iterator在范围内,所以我无法理解错误的来源。

This line doesn't do what you think it does. 这条线不符合你的想法。

impl Iterator for MyReader {

This implements Iterator for the trait object MyReader . 这实现了特征对象 MyReader Iterator What you want is to implement Iterator for every type which also implements MyReader . 你想要的是为每个也实现MyReader类型实现Iterator Unfortunately, this is not possible due to the coherence rules. 不幸的是,由于一致性规则,这是不可能的。

In Rust, you can only implement a trait in either the crate that defines the trait, or the crate that defines the type you are implementing it on. 在Rust中,您只能在定义特征的包中或在定义要实现它的类型的包中实现特征。 (Things are a bit more complicated for generic types, but that's the basic idea.) In this case, Iterator is a trait from the standard library, so there is no way for you to implement it on arbitrary types that you didn't define. (对于泛型类型来说事情有点复杂,但这是基本的想法。)在这种情况下, Iterator是标准库的特征,所以没有办法在你没有定义的任意类型上实现它。 If you think about it, this makes sense, because otherwise you'd get ambiguity if one of those types has a pre-existing implementation of Iterator - which one would be used? 如果你考虑一下,这是有道理的,因为如果其中一个类型有一个预先存在的Iterator实现 - 你将使用哪一个,你会变得模棱两可?

One solution is to wrap the type implementing MyReader in a newtype, and implement Iterator on that. 一种解决方案是将实现MyReader的类型包装在MyReader中,并在其上实现Iterator Since you defined the newtype yourself, you are free to implement Iterator on it. 由于您自己定义了newtype,因此可以自由地在其上实现Iterator

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

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