2016-09-03 5 views
7

私はFlatMapの項目のすべての可能なペアを作成しようとしています:std :: iter :: FlatMap.clone()は可能ですか?

possible_children.clone().flat_map(|a| possible_children.clone().map(|b| (a,b))) 

これを行うためには、FlatMap構造体はcloneメソッドを実装していることを私はFlatMapのクローンを作成しようとしていると私は、マニュアルで見ます。しかし、特性境界を満たすFlatMapを作成することはできないようです。

これは私が取得していますエラーです:Fの両方に拘束されているように見えます

impl<I, U, F> Clone for FlatMap<I, U, F> 
    where F: Clone, I: Clone, U: Clone + IntoIterator, U::IntoIter: Clone 

impl<I, U, F> Iterator for FlatMap<I, U, F> 
    where F: FnMut(I::Item) -> U, I: Iterator, U: IntoIterator 

error: no method named `clone` found for type `std::iter::FlatMap<std::ops::Range<u16>, _, [[email protected]/main.rs:30:47: 33:27]>` in the current scope 
    --> src/main.rs:37:66 
    | 
37 |   possible_children.clone().flat_map(|a| possible_children.clone().map(|b| (a,b))) 
    |                 ^^^^^ 
    | 
    = note: the method `clone` exists but the following trait bounds were not satisfied: `[[email protected]/main.rs:30:47: 33:27] : std::clone::Clone` 

は、私が見るドキュメントを見ますClone形質及びFnMut形質が可能であるが、 eを入力してFnMutCloneの両方を実装します。

ドキュメントには呼び出すことができないメソッドが存在することがありますので、何か不足しているはずです。

誰かが私に明確にしてもらえますか?

MVCE:

fn main() { 
    let possible_children = (0..10).flat_map(|x| (0..10).map(|y| (x,y))); 

    let causes_error = possible_children.clone().flat_map(|a| 
     possible_children.clone().map(|b| (a,b)) 
    ).collect(); 

    println!("{:?}",causes_error); 
} 
+0

あなたが使用しようとしている 'possible_children'の値は何ですか?そのエラーは何ですか? – Dogbert

+0

possible_childrenの実際の値はやや複雑ですが、これは同じエラーを返します: 'let possible_children =(0..10).flat_map(| x | (0..10).map(| y |(x、y) )) ); ' –

答えて

8

タイプは実装できないことには固有の理由はありません両方FnMutCloneが、現時点では閉鎖がCloneを実装していないようです。ここに簡略discussion about this from 2015があります。私は(まだ)これ以上の最近の議論を発見していない。

私は、そう毎晩コンパイラ(playgroundFlatMapが不安定な機能を必要と私自身の構造体、上FnMutを実装することによりクローン化され、この例を構築することができました:あなたはデカルトを作成している

#![feature(unboxed_closures)] 
#![feature(fn_traits)] 
struct MyFun { 
    pub v: usize, 
} 

impl FnOnce<(usize,)> for MyFun { 
    type Output = Option<usize>; 
    extern "rust-call" fn call_once(self, args: (usize,)) -> Self::Output { 
     Some(self.v + 1 + args.0) 
    } 

} 

impl FnMut<(usize,)> for MyFun { 
    extern "rust-call" fn call_mut(&mut self, args: (usize,)) -> Self::Output { 
     self.v += 1; 
     if self.v % 2 == 0 { 
      Some(self.v + args.0) 
     } else { 
      None 
     } 
    } 
} 

impl Clone for MyFun { 
    fn clone(&self) -> Self { 
     MyFun{v: self.v} 
    } 
} 

fn main() { 
    let possible_children = (0..10).flat_map(MyFun{v:0}); 
    let pairs = possible_children.clone().flat_map(|x| possible_children.clone().map(move |y| (x,y))); 
    println!("possible_children={:?}", pairs.collect::<Vec<_>>()); 
} 
3

イテレータのアイテムセットと別のイテレータのアイテムの積。あなたはitertools箱の.cartesian_product() adaptorを使用できます。

+0

実際には、同じイテレータの2つのコピーのデカルト積が必要です。だから彼はまだ '.cartesian_product()'に2番目の引数として渡すためにイテレータをクローンする必要がありますか? –

関連する問題