पाठ 18 / 25
Iterators and Closures
map, filter, sum, collect.
Lazy, composable, zero-cost
Iterators produce values one at a time; adapters such as map, filter, take and enumerate build lazy pipelines that run only when consumed by sum, count, collect, max_by_key or a for loop. Closures (|o| o.amount > threshold) capture variables from their environment. Iterator chains compile to code as fast as hand-written loops while being clearer. iter() borrows items, into_iter() takes ownership, iter_mut() borrows mutably.
Processing orders with iterator chains, run
I ran this with Rust 1.99.0 (cargo run, edition 2024, standard library only). Paid orders sum to 3,057; names are collected into a Vec; max_by_key finds Meera's order; map applies a 10% discount; a closure captures the threshold; position finds the first unpaid order.
#[derive(Debug)]
struct Order { customer: &'static str, amount: u32, paid: bool }
fn main() {
let orders = vec![
Order { customer: "Asha", amount: 1259, paid: true },
Order { customer: "Ravi", amount: 1200, paid: false },
Order { customer: "Meera", amount: 1798, paid: true },
];
let paid_total: u32 = orders.iter().filter(|o| o.paid).map(|o| o.amount).sum();
let names: Vec<&str> = orders.iter().map(|o| o.customer).collect();
let biggest = orders.iter().max_by_key(|o| o.amount).unwrap();
let discounted: Vec<u32> = orders.iter().map(|o| o.amount * 90 / 100).collect();
let threshold = 1250; // closures capture variables
let above = orders.iter().filter(|o| o.amount > threshold).count();
println!("paid total {paid_total}");
println!("{names:?} biggest={}", biggest.customer);
println!("{discounted:?} above {threshold}: {above}");
let first_unpaid = orders.iter().position(|o| !o.paid);
println!("first unpaid index {first_unpaid:?}");
}
Output:
paid total 3057 ["Asha", "Ravi", "Meera"] biggest=Meera [1133, 1080, 1618] above 1250: 2 first unpaid index Some(1)
Prefer iterators over index loops
Iterators avoid bounds checks and off-by-one errors; clippy even suggests them.
त्वरित जाँच: When does a chain like iter().map(...).filter(...) actually run?
- When it is consumed, for example by sum, collect or a for loop
- Immediately when map is called
- At compile time
- Never
Answer
When it is consumed, for example by sum, collect or a for loop — Iterators are lazy.