Skip to content

Iterators

Every collection exposes three ways to produce an iterator:

MethodYieldsOwnership
.iter()&TBorrows the collection
.iter_mut()&mut TBorrows the collection mutably
.into_iter()TConsumes (moves) the collection
let v = vec![1, 2, 3];
for x in v.iter() { } // v still valid after
for x in v.into_iter() { } // v moved — cannot use v after

Adaptors transform an iterator into another iterator. They do no work until driven by a consumer.

Transforms each element:

let doubled: Vec<i32> = vec![1, 2, 3].iter().map(|&x| x * 2).collect();
// [2, 4, 6]

Keeps elements matching a predicate. Note: .iter() on Vec<i32> yields &&i32 inside filter — destructure with |&&x|:

let evens: Vec<i32> = vec![1, 2, 3, 4].iter().filter(|&&x| x % 2 == 0).map(|&x| x).collect();
// [2, 4]

Pairs each element with its index (usize, &T):

for (i, val) in vec!["a", "b", "c"].iter().enumerate() {
println!("[{}] {}", i, val);
}

Combines two iterators element-by-element into (A, B) pairs, stopping at the shorter one:

let names = vec!["Alice", "Bob"];
let scores = vec![100, 85];
for (name, score) in names.iter().zip(scores.iter()) {
println!("{}: {}", name, score);
}

A consumer pulls values through the adaptor chain and produces a final result.

ConsumerResult
.collect::<Vec<T>>()Builds a collection
.sum::<i32>()Sums numeric elements
.fold(init, f)Reduces to a single value with accumulator
.count()Counts elements
.any(pred) / .all(pred)Short-circuit boolean tests
let nums = vec![1, 2, 3, 4, 5];
let total: i32 = nums.iter().sum(); // 15
let product: i32 = nums.iter().fold(1, |acc, &x| acc * x); // 120
fn main() {
let numbers = vec![1, 2, 3, 4, 5, 6];
// filter + map + collect
let evens_doubled: Vec<i32> = numbers
.iter()
.filter(|&&x| x % 2 == 0)
.map(|&x| x * 2)
.collect();
println!("evens doubled: {:?}", evens_doubled);
// enumerate
for (i, val) in numbers.iter().enumerate() {
println!("[{}] = {}", i, val);
}
// zip two iterators
let letters = vec!["a", "b", "c"];
for (n, l) in numbers.iter().take(3).zip(letters.iter()) {
println!("{} -> {}", n, l);
}
// consumers: sum and fold
let total: i32 = numbers.iter().sum();
let product: i32 = numbers.iter().fold(1, |acc, &x| acc * x);
println!("sum={} product={}", total, product);
}
What is the key difference between .iter() and .into_iter() on a Vec?
When does a .map() adaptor actually execute its closure?
What does .fold(0, |acc, &x| acc + x) compute for vec![1, 2, 3]?
Why does a filter closure on .iter() of Vec<i32> receive &&i32?