2016-09-03 23 views
7

Próbuję utworzyć wszystkie możliwe pary elementów w FlatMap:Czy możliwe jest użycie std :: iter :: FlatMap.clone()?

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

Aby to zrobić, próbuję sklonować FlatMap i widzę w dokumentacji, że FlatMap struct implementuje metodę clone . Ale nie wydaje się możliwe stworzenie takiego, który spełniałby granice cech.

Jest to błąd otrzymuję:

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` 

Patrząc na dokumentacji widzę:

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

i

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

Wygląda F jest związany zarówno Clone cecha i cecha FnMut, ale nie jest to możliwe e za coś, co zaimplementuje oba: FnMut i Clone.

Wydaje się dziwne, że w dokumentacji, do której nie można zadzwonić, istnieje metoda, więc muszę czegoś pomijać.

Czy ktoś może mi wyjaśnić?

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

Jaka jest wartość 'possible_children', której próbujesz użyć, która daje ten błąd? – Dogbert

+0

Rzeczywista wartość possible_children jest nieco skomplikowana, ale daje ten sam błąd: 'let possible_children = (0..10) .flat_map (| x | (0..10) .map (| y | (x, y)) ); ' –

Odpowiedz

8

Nie ma właściwy powód, że typ nie może realizować zarówno FnMut i Clone, ale wydaje się, że w momencie zamknięcia nie wdrażają Clone. Oto krótki discussion about this from 2015. Nie znalazłem (jeszcze) żadnej nowszej dyskusji.

udało mi się skonstruować ten przykład gdzie FlatMap jest sklonowany przez wdrożenie FnMut na własnej struktury, która wymaga niestabilne możliwości, więc nocne kompilatora (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<_>>()); 
} 
3

tworzysz kartezjańskiej iloczyn zestawu elementów w iteratorze z zestawem innego elementu. Do tego celu można użyć .cartesian_product() adaptor ze skrzynki itertools.

+0

Właściwie, chce produktu kartezjańskiego dwóch kopii tego samego iteratora. Więc nadal musi sklonować iterator, aby przekazać go jako drugi argument do '.cartesian_product()', nie? –

Powiązane problemy