Rust has two main traits for iteration: the standard Iterator
for things that can be traversed in order, and DoubleEndedIterator
for things that can additionally be iterated from the back.
This makes sense to me. A lot of useful methods are defined on Iterator
, like map
, filter
, and whatnot. And then things that operate from the "back", so to speak, like rfind
and rfold
are defined on DoubleEndedIterator
since such operations only make sense on such iterators.
But then we've got Iterator::rev
fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator, { Rev::new(self) }
rev
is a function defined on Iterator
but with an additional constraint on Self
that it be DoubleEndedIterator
as well.
What is the practical benefit to having this function defined on Iterator
? We can only call it on DoubleEndedIterator
implementors, and DoubleEndedIterator
extends Iterator
so we'll never end up in a situation where something implements the former and not the latter. So why is rev
not defined on DoubleEndedIterator
like rfind
and rfold
are?
DoubleEndedIteratorExt
that requiredDoubleEndedIterator + Sized
. TheDoubleEndedIteratorExt
trait was then merged intoIterator
. I can't see why it wasn't merged intoDoubleEndedIterator
instead. – InweaveIterator::rev
thanDoubleEndedIterator::rev
. – CrannogRev
aka be a doubleendediterator and OP didn't ask for why it's not merged – CranDoubleEndedIterator
on theIterator
triait,partition_in_place()
andrposition()
. Looking at the methods that are onDoubleEndedIterator
proper, it looks like they are the ones that are useful to specialize for specific bidirectional iterators, while the ones on theIterator
trait generally are not useful to specialize. Whether this is the reason they are split up this way, I don't know. I also don't see a forcing reason why it should be this way, since methods on either trait could be specialized. – Inweave