The Iterator Trait
Iterator requires fn next(&mut self) -> Option<Self::Item>. Adapters chain lazily until consumption.
Recipe
struct Counter { n: u32, max: u32 }
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.n < self.max { let v = self.n; self.n += 1; Some(v) } else { None }
}
}
fn main() {
let sum: u32 = Counter { n: 0, max: 5 }.sum();
println!("{sum}");
}When to reach for this: Custom sequences, parsers, and lazy pipelines.
Working Example
struct Lines<'a> { s: &'a str }
impl<'a> Iterator for Lines<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
if self.s.is_empty() { return None; }
let (line, rest) = match self.s.find('\n') {
Some(i) => (&self.s[..i], &self.s[i + 1..]),
None => (self.s, ""),
};
self.s = rest;
Some(line)
}
}What this demonstrates:
- Borrowing iterator over
&str - Associated type
Item = &str - Manual state in struct fields
Deep Dive
Iterator provides default methods: map, filter, fold, etc. IntoIterator enables for loops.
size_hint optimization optional. FusedIterator documents end behavior.
Gotchas
- Infinite iterator + collect - Hangs. Fix:
take(n)bound. - Iterator invalidation on source - Mutating
Vecwhile iterating it. Fix: Collect indices or clone. - Forgetting
#[must_use]laziness - No work until consume. Fix: Assign to_ = iter.count()if intentional. - Custom Iterator not fused - Extra
nextafterNonemay repeat. Fix: Document or useFusedIterator. - GAT lending iterators - Advanced - return borrowed items with GAT
Item<'a>.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
for loop index | Need neighbors | Simple map/filter |
| Recursion | Trees | Deep stack risk |
gen blocks (nightly) | Generator style | Stable custom Iterator |
FAQs
IntoIterator?
for loop calls into_iter.iter vs into_iter?
borrow vs own.DoubleEndedIterator?
next_back for reverse.ExactSizeIterator?
len known - optimizations.extend trait?
for loop push via Extend.flatten?
Iterator of iterators.try_iterator?
Fallible variants.no_std?
core::iter.async iter?
Stream trait async ecosystems.clippy?
manual_flatten etc.Related
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.