13.4 Advanced Iterator Traits
Beyond the base Iterator
trait, several others provide additional capabilities and enable optimizations:
DoubleEndedIterator
: For iterators that can efficiently yield elements from both the front (next()
) and the back (next_back()
). Enables methods likerev()
. Implemented by iterators over slices,VecDeque
, ranges, etc.fn main() { let numbers = vec![1, 2, 3, 4, 5]; let mut iter = numbers.iter(); // slice::Iter implements DoubleEndedIterator assert_eq!(iter.next(), Some(&1)); // Consume from front assert_eq!(iter.next_back(), Some(&5)); // Consume from back assert_eq!(iter.next(), Some(&2)); assert_eq!(iter.next_back(), Some(&4)); // Remaining elements are [&3]. let remaining: Vec<&i32> = iter.collect(); assert_eq!(remaining, vec![&3]); // Use rev() on a double-ended iterator let reversed: Vec<&i32> = numbers.iter().rev().collect(); assert_eq!(reversed, vec![&5, &4, &3, &2, &1]); }
ExactSizeIterator
: For iterators that know precisely how many elements remain. Provideslen()
method returning the exact count. Allows consumers likecollect()
to potentially pre-allocate capacity, improving performance. Implemented by iterators over slices, arrays,Vec
,VecDeque
, simple ranges, etc. Note: Adapters likefilter
orflat_map
typically produce iterators that are notExactSizeIterator
, as the final count isn’t known without iterating through them.fn main() { let numbers = vec![10, 20, 30, 40]; let mut iter = numbers.iter(); // slice::Iter implements ExactSizeIterator assert_eq!(iter.len(), 4); iter.next(); assert_eq!(iter.len(), 3); // A filtered iterator does not know its exact size in advance let filtered_iter = numbers.iter().filter(|&&x| x > 15); // The following line would cause a compile error: // assert_eq!(filtered_iter.len(), 3); // Error: no method named `len` found // However, ALL iterators provide `size_hint()` // size_hint() returns (lower_bound, Option<upper_bound>) assert_eq!(filtered_iter.size_hint(), (0, Some(4))); // May be 0 to 4 elements let collected: Vec<_> = filtered_iter.collect(); // Iteration happens here assert_eq!(collected.len(), 3); // Actual count after iteration }
size_hint()
: A method available on all iterators via theIterator
trait. Returns a tuple(lower_bound, Option<upper_bound>)
estimating the number of remaining elements. The lower bound is guaranteed to be accurate. ForExactSizeIterator
,lower_bound == upper_bound.unwrap()
, andlen()
is simply a convenience method for this.size_hint
is used internally by methods likecollect
to make initial capacity reservations.FusedIterator
: A marker trait indicating that once the iterator returnsNone
, all subsequent calls tonext()
(andnext_back()
if applicable) are guaranteed to returnNone
. Most standard iterators are fused. This allows consumers to potentially optimize by not needing to callnext()
again after the firstNone
. Custom iterators should uphold this behavior if possible and can implement this marker trait.