Coding/Learn/rust/iterators and closures
Rust Foundational Course
01.Introduction to Rust & Memory Safety
02.Formatting, Comments & Macros (println!)
03.Variables, Mutability & Shadowing
04.Scalar & Compound Types (Integers, Floats, Tuples, Arrays)
05.Functions, Parameters & Return Expressions
06.Conditionals & If as an Expression
07.Ownership Rules & Move Semantics
08.References & Borrowing (&T)
09.Mutable References (&mut) & Aliasing XOR Mutability
10.Slices & String Types (&str vs String)
11.Loops in Rust (loop, while, for)
12.Pattern Matching with match Expressions
13.Structs, Associated Functions & Methods (impl)
14.Enums & the Option<T> Type (No Null!)
15.Concise Pattern Matching (if let & let else)
16.Vectors & Growable Collections (Vec<T>)
17.Error Handling with Result<T, E> & the ? Operator
18.Traits, Shared Behavior & Generics
19.Closures & Functional Iterators (map, filter, collect)
20.Capstone: High-Performance In-Memory Log Telemetry Engine
Course Certificate0%

Complete all lessons to earn

LearnClosures & Functional Iterators (map, filter, collect)
19 / 20 0%
Lesson 19 of 20
6 mins read

Closures & Functional Iterators (map, filter, collect)

PreviousNext Lesson
In Plain English

Closures are anonymous functions that can capture variables from their enclosing environment (|param| expr). Combined with Rust’s lazy Iterator trait adaptors (.map, .filter, .fold, .collect), they produce zero-cost functional data transformation pipelines.

The Mental Model

"Iterator adaptors are like interlocking industrial conveyor sections: .filter() drops defective parts, .map() polishes them, and .collect() packs them into a finished crate—and the whole conveyor only spins when the final crate is demanded (lazy evaluation)."

Deep Dive: How It Works

Closures: Anonymous functions defined with vertical bars: |x, y| x + y.

Lazy Iterators: Iterator adaptors do no work until a consuming method like .collect(), .sum(), or .count() is called.

.collect(): Assembles transformed iterator streams back into collections like Vec<T>.

Syntax Blueprint

let doubled: Vec<i32> = numbers.iter().filter(|&&x| x > 5).map(|x| x * 2).collect();

Chains functional transformation stages into a single optimized SIMD loop.

PointCore Rules to Remember

Point star
Zero-Cost Abstractions: Iterator pipelines compile to the exact same assembly as hand-tuned C loops.
Point star
Lazy Evaluation: Adaptors process elements on-demand without intermediate allocations.
Point star
Closures (|x| ...): Capture surrounding variables automatically by reference or move.

Common Beginner Traps & How to Fix Them

Mistake:Forgetting type annotation on .collect().

Why it happens: collect() can build Vec, HashSet, String, etc. The compiler needs to know target collection type.

How to fix: Use let res: Vec<i32> = ... or .collect::<Vec<_>>() (the turbofish operator).

Pro Tip: Use .into_iter() if you want to consume the collection and own the elements inside closure adaptors.

Live Interactive Example

Hit Run Code to see it live
Composing Iterator Pipelines
Rust 1.78 / rustc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Output Console
Click "Run Code" to view the rendered output.
How it works: Demonstrates functional iterator chaining with filter, map, and collect.

Your Turn: Micro Challenge

No pressure! Edit the starter code below and test your solution with instant feedback.

Micro Exercise

Filter and double numbers with iterator

  • PointGiven let numbers = vec![1, 2, 3, 4, 5];
  • PointUse .into_iter().filter(|x| x % 2 == 0).map(|x| x * 10).collect::<Vec<i32>>()
  • PointPrint "Even doubled: [20, 40]".
1
2
3
4
5
6
Sandbox Output
Click "Run & Check" to test your solution.

Finished reading and practicing?

Mark this lesson as completed to update your course progress.

PreviousNext Lesson
Overview100 SheetLearnCertificates