rust clone flatmap

rust - Es posible std:: iter:: FlatMap.clone()?



(2)

Está creando el producto cartesiano del conjunto de elementos en un iterador con el de otro. Puede usar el adaptador .cartesian_product() del cajón itertools para eso.

Estoy tratando de crear todos los pares posibles de elementos en un FlatMap :

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

Para hacer esto, intento clonar un FlatMap y veo en la documentación que la estructura de FlatMap implementa un método de clone . Pero no parece posible crear un FlatMap que satisfaga los límites de rasgo.

Este es el error que estoy recibiendo:

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`

Mirando la documentación que veo:

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

y

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

Parece que F está vinculado tanto por el rasgo Clone como por el rasgo FnMut , pero no es posible que algo implemente tanto FnMut como Clone .

Parece extraño que exista un método en la documentación que no es posible llamar, así que me falta algo.

¿Alguien puede aclarar por mí?

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


No hay ninguna razón inherente para que un tipo no pueda implementar tanto FnMut como Clone , pero parece que en este momento los cierres no implementan Clone . Aquí hay una breve discusión sobre esto desde 2015 . No (todavía) encontré ninguna discusión más reciente.

Pude construir este ejemplo donde se clona un FlatMap implementando FnMut en mi propia estructura, que requiere funciones inestables, por lo que un compilador nocturno ( patio de recreo ):

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