Crash Courses · PhD
Closures & Iterators
Functional patterns that compile to zero-cost loops
35 min read+185 XP on completionCert: Rust Crash Course
Tap any word in the text below to start reading from there.
Closures & Iterators
Closures
fn main() {
let x = 10;
let add_x = |n| n + x; // captures x by reference
println!("{}", add_x(5)); // 15
println!("{}", add_x(20)); // 30
// Closures as function arguments
let nums = vec![1, 2, 3, 4, 5];
let doubled: Vec<i32> = nums.iter().map(|n| n * 2).collect();
println!("{:?}", doubled); // [2, 4, 6, 8, 10]
}Closure Traits
- Fn — can be called multiple times, captures by reference
- FnMut — can be called multiple times, captures by mutable reference
- FnOnce — can only be called once, captures by value (moves captured data)
fn apply<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
f(x)
}
fn apply_once<F: FnOnce() -> String>(f: F) -> String {
f() // f is consumed here
}
let greet = || "Hello".to_string();
println!("{}", apply_once(greet));Iterator Chains
let scores = vec![85, 92, 45, 78, 60, 95, 30];
let top_students: Vec<String> = scores.iter()
.enumerate() // (index, value) pairs
.filter(|(_, &score)| score >= 80) // keep only high scores
.map(|(i, score)| format!("Student {} scored {}", i + 1, score))
.collect();
for s in &top_students {
println!("{}", s);
}Common Iterator Methods
let v = vec![1, 2, 3, 4, 5];
// sum and product
let total: i32 = v.iter().sum(); // 15
let product: i32 = v.iter().product(); // 120
// fold (generic reduce)
let sum = v.iter().fold(0, |acc, x| acc + x); // 15
// find — returns Option
let first_even = v.iter().find(|&&x| x % 2 == 0); // Some(2)
// any / all
let has_big = v.iter().any(|&x| x > 4); // true
let all_pos = v.iter().all(|&x| x > 0); // true
// flatten
let nested = vec![vec![1, 2], vec![3, 4]];
let flat: Vec<i32> = nested.into_iter().flatten().collect(); // [1,2,3,4]
// zip
let names = vec!["Alice", "Bob"];
let ages = vec![30, 25];
let pairs: Vec<_> = names.iter().zip(ages.iter()).collect();
// [("Alice", 30), ("Bob", 25)]Implementing Iterator
struct Counter {
count: u32,
max: u32,
}
impl Counter {
fn new(max: u32) -> Self { Counter { count: 0, max } }
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<u32> {
if self.count < self.max {
self.count += 1;
Some(self.count)
} else {
None
}
}
}
// Now Counter gets all iterator adapters for free
let sum: u32 = Counter::new(5).sum(); // 15Reading progress
0% read
In this module
Closure
Iterator trait
map()
filter()
0%