The Iterator trait requires just one method, next(), which returns Some(item) or None when exhausted. Iterators are lazy: calling .map() or .filter() builds up a chain of transformations but produces no output on its own — nothing runs until a consuming method like .collect(), .sum(), or a for loop actually pulls values through the chain. Because of how the compiler optimizes these chains, iterator code typically compiles to loops just as fast as hand-written ones.
Creating and consuming an iterator
.iter() produces an iterator of references over a collection; a for loop is a consuming method that pulls every item through automatically.
let v = vec![1, 2, 3];
let mut iter = v.iter();
println!("{:?}", iter.next()); // Some(1)
println!("{:?}", iter.next()); // Some(2)
println!("{:?}", iter.next()); // Some(3)
println!("{:?}", iter.next()); // None — exhausted
for x in v.iter() { // idiomatic: for loop consumes the iterator
println!("{}", x);
}Laziness: nothing happens until you consume
Building a chain of adapters like map and filter creates a description of the work, but performs none of it — the underlying closures are never even called — until a consuming method drives the chain to completion.
let v = vec![1, 2, 3, 4, 5];
let chain = v.iter().map(|x| {
println!("processing {}", x); // this print never runs yet!
x * 2
});
// nothing has printed at this point — chain hasn't been consumed
let doubled: Vec<i32> = chain.collect(); // NOW it runs, prints 5 times
println!("{:?}", doubled); // [2, 4, 6, 8, 10]Common adapters: map, filter, collect
Adapter methods chain together to express a data transformation declaratively; .collect() is the most common consumer, gathering results into a Vec, String, HashMap, or any type implementing FromIterator.
let numbers = vec![1, 2, 3, 4, 5, 6];
let result: Vec<i32> = numbers
.iter()
.filter(|&&x| x % 2 == 0) // keep evens: [2, 4, 6]
.map(|x| x * x) // square them: [4, 16, 36]
.collect();
println!("{:?}", result); // [4, 16, 36]
let total: i32 = numbers.iter().sum(); // consumes directly, no collect needed
println!("{}", total); // 21