Iterators

The Iterator Trait

The std::iter::Iterator trait is the core interface implemented by all iterators in Rust, requiring only an associated Item type and a next(&mut self) method while providing over 70 default adapter and consumer methods.

Trait Definition

pub trait Iterator {
    type Item;

    // Required method:
    fn next(&mut self) -> Option<Self::Item>;

    // Selected provided methods with default implementations:
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
    fn count(self) -> usize { /* ... */ }
    fn nth(&mut self, n: usize) -> Option<Self::Item> { /* ... */ }
    fn map<B, F>(self, f: F) -> Map<Self, F> { /* ... */ }
    fn filter<P>(self, predicate: P) -> Filter<Self, P> { /* ... */ }
    fn collect<B: FromIterator<Self::Item>>(self) -> B { /* ... */ }
}
  • type Item specifies the type of element yielded by the iterator (for example, &T, &mut T, or an owned T).
  • fn next(&mut self) -> Option<Self::Item> advances the iterator by one step and returns Some(item), or None when iteration is finished.

Companion Iterator Traits in std::iter

In addition to Iterator, the standard library defines specialized subtraits that unlock extra capabilities when the underlying source supports them:

Trait Required Method(s) Capabilities Unlocked
DoubleEndedIterator: Iterator next_back(&mut self) -> Option<Self::Item> Iterating from the back (.rev(), .rfind(), .rposition())
ExactSizeIterator: Iterator len(&self) -> usize (via exact size_hint) O(1) remaining length queries (iter.len())
FusedIterator: Iterator Marker trait Guarantees next() always returns None forever after the first None
FromIterator<A> from_iter<T>(iter: T) -> Self Target container construction via .collect()

Using DoubleEndedIterator and ExactSizeIterator

Slice iterators (std::slice::Iter), ranges (0..10), and VecDeque iterators implement both DoubleEndedIterator and ExactSizeIterator:

fn main() {
    let mut iter = ["alpha", "beta", "gamma", "delta"].iter();

    println!("Initial len: {}", iter.len());
    println!("From front:  {:?}", iter.next());
    println!("From back:   {:?}", iter.next_back());
    println!("Remaining:   {}", iter.len());

    let reversed_rest: Vec<&&str> = iter.rev().collect();
    println!("Rest (rev):  {reversed_rest:?}");
}
Initial len: 4
From front:  Some(&"alpha")
From back:   Some(&"delta")
Remaining:   2
Rest (rev):  [&"gamma", &"beta"]