2017-01-17 6 views
1

私は、各ブランチが異なるタイプを返すことができる一致を実行しようとするコードを持っていますが、はすべてIterator<Item=usize>を実装しています。イテレータを返すマッチアーム?

let found: Iterator<Item = usize> = match requirements { 
    Requirements::A => MatchingAs { ainternals: [] }, 
    Requirements::B => MatchingBs { binternals: [] }, 
    Requirements::C => MatchingCs { cinternals: [] }, 
}; 

return found.any(|m| m == 1) 

...どこMatchingAsMatchingBs、およびMatchingCsすべてimplstd::iter::Iterator<Item = usize>

私はIteratorがサイズにされていないという事実と壁当たっている:

| the trait `std::marker::Sized` is not implemented for `std::iter::Iterator<Item=usize>` 

を一致アームが共有特性を持つオブジェクトを返し、その後、頼る持っている良い方法はあります(のみ)結果を処理する際の特性について?

+1

これは[イテレータを返すための正しい方法?](http://stackoverflow.com/q/27535289/155423)の重複しない理由を説明してください – Shepmaster

答えて

4

あなたがSizedではない何かを返したい最初の反射が、それは(別名、ポインタを、ヒープ上に置く返す)Boxにある:

これはここでは、十分ではありません
let found: Box<Iterator<Item = usize>> = match requirements { 
    Requirements::A => Box::new(MatchingAs { ainternals: [] }), 
    Requirements::B => Box::new(MatchingBs { binternals: [] }), 
    Requirements::C => Box::new(MatchingCs { cinternals: [] }), 
}; 

found.any(|m| m == 1) 

Box<MatchingBs>Box<MatchingAs>impl Trait for Concreteがあるたびに、...

しかし、Box<Concrete>はそう、Box<Trait>にキャストすることができます:今matchはあなたが別の型を返すことに文句を言うでしょうなぜなら

利用ジェネリック:
let found = match requirements { 
    Requirements::A => Box::new(MatchingAs { ainternals: [] }) as Box<Iterator<Item = usize>>, 
    Requirements::B => Box::new(MatchingBs { binternals: [] }) as Box<Iterator<Item = usize>>, 
    Requirements::C => Box::new(MatchingCs { cinternals: [] }) as Box<Iterator<Item = usize>>, 
}; 

found.any(|m| m == 1) 

は、しかし、割り当てのないソリューションがあります。

fn search<T: Iterator<Item = usize>>(t: T) -> bool { 
    t.any(|m| m == 1) 
} 

、その後matchの各ブランチにその関数を適用します。

match requirements { 
    Requirements::A => search(MatchingAs {ainternals: []}), 
    Requirements::B => search(MatchingBs {binternals: []}), 
    Requirements::C => search(MatchingCs {cinternals: []}), 
} 

トレードオフは、それがコールバック地獄をするために、やや間接的な流れに少し近いということです。

関連する問題