AnyCompiler

Iterators and Closures

Iterator methods like map and filter transform a collection lazily, without allocating anything until collect pulls the results into a concrete type like a Vec. The closure passed to map runs once per element.

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();
    println!("{:?}", doubled);

    let evens: Vec<&i32> = numbers.iter().filter(|&&x| x % 2 == 0).collect();
    println!("{:?}", evens);
}
Output
[2, 4, 6, 8, 10]
[2, 4]

Closures capture their environment

A closure, written |params| expression, can use variables from the scope it was defined in — multiply below captures factor from main, something a plain fn can't do.

fn main() {
    let factor = 3;
    let multiply = |x: i32| x * factor;

    println!("{}", multiply(5));
    println!("{}", multiply(10));
}
Output
15
30

Next: traits — defining shared behavior that different types can implement.

Practice exercise

Given numbers: Vec<i32> = vec![1, 2, 3, 4], use .iter().map() with a closure to square each number, collect into a Vec<i32>, and print it with {:?}.