Is it possible std :: iter :: FlatMap.clone ()?

I am trying to create all possible pairs of elements in FlatMap :

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

To do this, I try to clone FlatMap , and I see in the documentation that the FlatMap implements the clone method. But it is not possible to create a FlatMap that satisfies the boundaries of features.

This is the error I get:

 error: no method named `clone` found for type `std::iter::FlatMap<std::ops::Range<u16>, _, [ closure@src /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: `[ closure@src /main.rs:30:47: 33:27] : std::clone::Clone` 

Looking at the documentation, I see:

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

and

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

It looks like F is associated with both the clone attribute and FnMut , but it is impossible to implement something like FnMut and clone .

It seems strange that the method will exist in the documentation, which cannot be called, so I must skip something.

Can someone clarify me?

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); } 
+7
clone rust flatmap
source share
2 answers

There is no reason why a type cannot implement both FnMut and Clone , but it seems that at the moment, closures do not implement Clone . Here is a brief discussion about this since 2015 . I have not found a more recent discussion yet.

I managed to build this example when a FlatMap cloned by implementing FnMut in my own structure, which requires unstable functions, so the night compiler ( playground ):

 #![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<_>>()); } 
+8
source share

You create a Cartesian product of a set of elements in an iterator with another. You can use the .cartesian_product() adapter from itertools for this.

+3
source share

All Articles