2017-02-06 1 views
4

私は特性を持っており、構造体がこの特性を実装するならばIteratorとして機能することができます。しかし、イテレータとして構造体を使用しようとすると、コンパイラエラーが発生します。特性はIteratorを実装しますが、Iteratorとしての私の特性を実装する構造体を使用できません

私は、さまざまなファイル形式から同じ種類のデータを読み込むライブラリを作成しています。私は、適切な錆のオブジェクトを返します一般的な "リーダー"特性を作成したい。私は各リーダが反復子として動作し、そのオブジェクトを生成できると言いたいと思います。

ここでコード

/// 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(); 
} 

コンパイラの出力です:

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は錆の遊び場上のコードです。

MyVecMyReaderを実装しているので、イテレータとして使用できるはずですから、.next()を呼び出すことができます。 MyReaderを実装しているので、無料でIteratorの実装を取得する必要があります。行impl Iterator for ...は、Iteratorが範囲内にあることを示しているので、エラーの原因を理解できません。

+0

http://stackoverflow.com/q/34438755/155423およびhttp://stackoverflow.com/q/29256519/155423も参照してください。 – Shepmaster

答えて

4

この行は、あなたがそう思う行為ではありません。

impl Iterator for MyReader { 

これはtrait objectMyReaderためIteratorを実装しています。あなたが望むのは、MyReaderも実装するすべてのタイプに対してIteratorを実装することです。残念ながら、これは一貫性の規則のために可能ではありません。

Rustでは、形質を定義するクレートまたはそれを実装するタイプを定義するクレートのいずれかでのみ形質を実装できます。 (事柄はジェネリック型ではもう少し複雑ですが、それは基本的な考えです)。この場合、Iteratorは標準ライブラリの特性であるため、定義していない任意の型に実装する方法はありません。あなたがそれについて考えるなら、これは意味があります。そうでなければ、それらの型の1つがIteratorの既存の実装を持っていればあいまいさになります。

解決策の1つは、MyReaderを実装するタイプをnewtypeにラップし、その上にIteratorを実装することです。 newtypeは自分で定義したので、Iteratorを自由に実装することができます。

関連する問題