Closures & Iterators

Anonymous functions that capture their environment, and lazy iterator chains that compile to tight loops.

Closures are anonymous functions that can capture variables from where they are defined. Iterators produce values one at a time, and adaptors like map, filter and windows transform them lazily. Chains of iterator adaptors compile to the same machine code as hand-written loops — 'zero-cost abstractions'.

Analysing readings

is_hot captures limit from its surroundings.

filter keeps matching items; collect builds a Vec from the iterator.

enumerate + max_by finds the largest value and its index in one pass.

windows(2) yields overlapping pairs, perfect for differences between consecutive readings.

take_while stops at the first reading that fails the test; fold builds any result from all items.

check is a mutable closure (FnMut) because it changes alarms.

Fn, FnMut, FnOnce

readings.iter().map(|t| t * 2.0); // nothing happens let doubled: Vec<f64> = readings.iter().map(|t| t * 2.0).collect();

Iterator adaptors are lazy; without a consumer the closure never runs (the compiler warns about this unused iterator).

Why are iterator chains not slower than loops in Rust?

Each adaptor is a small generic struct; after monomorphization and inlining the optimizer fuses the chain into a single loop with no allocations or virtual calls.