I would like to optionally reverse an iterator, like this. But the types in my construction are incompatible:
error[E0308]: if and else have incompatible types
--> src/main.rs:4:16
|
4 | let iter = if reversed {
| ________________^
5 | | v.iter().rev()
6 | | } else {
7 | | v.iter()
8 | | };
| |_____^ expected struct `std::iter::Rev`, found struct `std::slice::Iter`
|
= note: expected type `std::iter::Rev<std::slice::Iter<'_, _>>`
found type `std::slice::Iter<'_, _>`
The reason not to use reverse() is that I would like to do some further processing of the items via map() and then extend another vector with the items. An intermediate collect() and reverse() would be less efficient. How would I accomplish this?
You can Box the iterator, but that adds some overhead, too. The next fn has to be called through a vtable, which is also harder for the compiler to optimize since the compiler is unlikely to be able to do any inlining.
fn main() {
let my_nums = vec![1,2,3,4];
let my_nums_iter: Box<Iterator<Item=_>> = if my_nums.len() > 4 {
Box::new(my_nums.iter())
} else {
Box::new(my_nums.iter().rev())
};
for x in my_nums_iter {
println!("{}", x);
}
}
You'd have to test to to see if doing an intermediate collect and reverse is more or less efficient than the boxed iterator.
You get this error because each iterator (each combination of iterators) is a different type, and Rust wants to optimize your code for one specific type.
Thank you for your answers! I tried the either-variant first. In my processing step of the items I need the chunk_exact function but it does not seem to exist, link.
Two small things: you don't need into_iter() since Either implements Iterator when both items are iterators, and since you are already using itertools, you can use collect_vec() to avoid having to annotate the type. (And yes, itertools is awesome.)