|
|
|
|
|
by onetoo
436 days ago
|
|
> Even more annoying is that I have to duplicate the iterator code: as I often work with frames that may be flipped bottom-up I want to write code like
>
> let mut iterator = if !flipped {
> data.chunks_mut(stride)
> } else {
> data.chunks_mut(stride).rev()
> };
> for line in iterator { ... }
>
> but I can’t since objects have different type (and probably size) and there’s no realistic way to coerce them to the same interface.
For this specific case there is a relatively ergonomic solution using dynamic trait objects + temporary lifetime extensions, available since Rust 1.79: let iterator: &mut dyn Iterator<Item = _> = if !flipped {
&mut data.into_iter()
} else {
&mut data.into_iter().rev()
};
for line in iterator { ... }
Alternatively, if this is not a feasible solution (e.g. we want to return the new iterator to an outer scope, or the overhead of dyn indirection is unacceptable in this context), one can consider using itertools::Either instead: use itertools::Either;
fn conditionally_flip_iter<I: DoubleEndedIterator>(
data: I,
flipped: bool,
) -> impl Iterator<Item = I::Item> {
if !flipped {
Either::Left(data.into_iter())
} else {
Either::Right(data.into_iter().rev())
}
}
// ...
let mut iterator = conditionally_flip_iter(data, flipped);
for line in iterator { ... }
|
|