Rust Closures and Iterators Explained: map, filter, collect and sum
November 10, 2026
Welcome to episode 20 of Rust for Beginners, a series for complete beginners (no programming experience needed). In the last video, we learned about generics. Today, we'll learn closures and iterators, two tools that make Rust code short and clear. Every code block below is the exact code from the video, ready to copy.
- All episodes are in the Rust Tutorial for Beginners playlist.
- Versions used: Rust 1.99.1 on Ubuntu, VS Code with rust-analyzer.
1. New project
Let's create a new project called closures, and open it in VS Code.
cargo new closures
cd closures2. Closure
A closure is a small function without a name, that we can store in a variable. The parameters go between two vertical bars, and the body comes after.
src/main.rs:
fn main() {
let add_one = |x: i32| x + 1;
println!("add_one(5) = {}", add_one(5));
let tax = 0.2;
let with_tax = |price: f64| price * (1.0 + tax);
println!("100 with tax: {}", with_tax(100.0));
}Output: add_one(5) = 6 / 100 with tax: 120
3. Call
We call it like any function: add one of five.
4. Capture
Unlike a normal function, a closure can use variables around it. with tax uses the tax variable from main. That's called capturing.
5. Run A
Let's run it. Six, and one hundred with tax is one hundred twenty.
cargo run6. Iterator
An iterator goes through items one by one. We get one from a vector with iter.
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
numbers.iter().map(|n| n * 2);
}Warning, and no output:
warning: unused `Map` that must be used
--> src/main.rs:3:5
|
3 | numbers.iter().map(|n| n * 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: iterators are lazy and do nothing unless consumed
= note: `#[warn(unused_must_use)]` (part of `#[warn(unused)]`) on by default
help: use `let _ = ...` to ignore the resulting value
|
3 | let _ = numbers.iter().map(|n| n * 2);
| +++++++7. map
map runs a closure on every item. Here, it doubles each number. Let's run it.
cargo run8. Lazy
Nothing happened, and Rust warns us: iterators are lazy and do nothing unless consumed. map only describes the work.
9. collect
To run it, we consume the iterator. collect gathers the results into a new vector.
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
let doubled: Vec<i32> = numbers.iter().map(|n| n * 2).collect();
println!("Doubled: {doubled:?}");
let evens: Vec<&i32> = numbers.iter().filter(|n| *n % 2 == 0).collect();
println!("Evens: {evens:?}");
let total: i32 = numbers.iter().sum();
println!("Total: {total}");
}Output: Doubled: [2, 4, 6, 8, 10] / Evens: [2, 4] / Total: 15
10. filter, sum
filter keeps only the items where the closure returns true, here the even numbers. And sum adds everything up.
11. Run B
Let's run it.
cargo run12. Chain
We can chain steps together. Keep the words longer than four letters, make them uppercase, and collect. Each step on its own line reads like a recipe.
fn main() {
let words = vec!["apple", "fig", "banana", "kiwi", "cherry"];
let long_words: Vec<String> = words
.iter()
.filter(|w| w.len() > 4)
.map(|w| w.to_uppercase())
.collect();
println!("{long_words:?}");
for (i, word) in words.iter().enumerate() {
println!("{i}: {word}");
}
let sum_of_odd_squares: i32 = (1..=10).filter(|n| n % 2 == 1).map(|n| n * n).sum();
println!("Sum of odd squares: {sum_of_odd_squares}");
}Output:
["APPLE", "BANANA", "CHERRY"]
0: apple
1: fig
2: banana
3: kiwi
4: cherry
Sum of odd squares: 16513. enumerate
enumerate gives each item together with its index.
14. Ranges
Ranges are iterators too. In one line: take one to ten, keep the odd numbers, square them, and add them up.
15. Run C
Let's run it.
cargo runRecap
To recap: a closure is an unnamed function that can capture its surroundings. Iterators are lazy. map and filter transform them, and collect, sum, or a for loop consume them.
16. `\
params\
src/main.rs:
fn main() {
let add_one = |x: i32| x + 1;
println!("add_one(5) = {}", add_one(5));
let tax = 0.2;
let with_tax = |price: f64| price * (1.0 + tax);
println!("100 with tax: {}", with_tax(100.0));
}Output: add_one(5) = 6 / 100 with tax: 120
17. Recap: `\
x\