'Returning an iterator type defined in another crate
I'm trying to forward an iterator through a function to give constructing the iterator a more friendly interface.
This was an attempt that didn't quite work
pub fn rep_cartesian_product<'a, T>(iter: T, n: i32)-> itertools::MultiProduct<T>
where T: Iterator + Clone {
(0..n).map(|_| iter).multi_cartesian_product()
}
One of the errors I get is:
"The trait std::clone::Clone is not implemented for <T as std::iter::Iterator>::Item". But I'm not sure why this is the case since I put + Clone in the where clause.
A prior attempt was
pub fn rep_cartesian_product<'a, T>(iter: T, n: i32)-> impl Iterator<Item = Vec<T>>
where T : Iterator {
(0..n).map(|_| iter).multi_cartesian_product()
}
type mismatch resolving <itertools::MultiProduct<T> as std::iter::Iterator>::Item == std::vec::Vec<T> which is why I tried the previous shared attempt.
Solution 1:[1]
You requested that the iterator be Clone, but you additionally need to request that the items it produces are themselves Clone with a trait bound like T::Item: Clone.
Additionally, (0..n).map(|_| iter) doesn't compile because map() expects a closure it can call multiple times, and returning iter makes the closure callable only once. You can fix that by switching to .map(|_| iter.clone()) - or by using std::iter::repeat() instead.
Here is a version that compiles:
pub fn rep_cartesian_product<T>(iter: T, n: usize) -> itertools::MultiProduct<T>
where
T: Iterator + Clone,
T::Item: Clone,
{
std::iter::repeat(iter).take(n).multi_cartesian_product()
}
Note that you can also return impl Iterator<Item = Vec<T::Item>>, which has the advantage of hiding the implementation of the iterator.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
