GGistDev

Iterators in Rust

Iterators are lazy sequences. The Iterator trait drives adapters (transformations) and consumers (execution).

Core trait

pub trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}

Producing iterators

  • iter() yields &T
  • iter_mut() yields &mut T
  • into_iter() yields T (by value)
let v = vec![1,2,3];
let sum: i32 = v.iter().copied().sum();

Adapters and consumers

let out: Vec<_> = (0..10)
    .filter(|n| n % 2 == 0)
    .map(|n| n * n)
    .take(3)
    .collect(); // [0,4,16]

let found = (1..).skip(5).find(|&n| n % 7 == 0);

Common consumers: collect, sum, product, fold, find, any, all, max_by.

Collecting into maps/sets

use std::collections::HashMap;
let pairs = vec![("a", 1), ("b", 2)];
let m: HashMap<_, _> = pairs.into_iter().collect();

Specify type to guide collect.

Ownership and borrowing

Adapters taking ownership (e.g., into_iter) move items; use iter + cloned/copied for sharing.

Implementing a custom iterator

struct Counter { n: u32 }
impl Counter { fn new() -> Self { Self { n: 0 } } }
impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<Self::Item> { self.n += 1; Some(self.n) }
}

Tips

  • Prefer iterator chains over indexed loops for clarity and safety.
  • Avoid intermediate allocations; iterators are lazy and fuse well with collect when needed.