JSTAcademy
0 XP
Dashboard
Crash Courses
Closures & Iterators
35 min
PhD+185 XP
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(); // 15
0%