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.
main.rs
Try it yourself →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.
main.rs
Try it yourself →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 {:?}.