Iterators

Contents
Iterator chains
Lazy by default
Collect results
Find fold any

Iterator chains

Iterators transform collections through small chained steps called adapters. Each adapter returns a fresh iterator, so steps snap together like pipe segments. The chain below keeps even numbers, doubles them, and adds everything up.

fn main() { let nums = vec![1, 2, 3, 4]; let total: i32 = nums.iter().filter(|x| *x % 2 == 0).map(|x| x * 2).sum(); println!("{}", total); }

Filter keeps what passes its test, map rewrites each survivor, and sum folds the rest into one number. No temporary vectors appear between steps. Reading the chain left to right tells the whole story.

Lazy by default

Adapters record a plan without running any of it. Real work starts only when something consumes the iterator, such as a for loop or sum. Building the plan below prints nothing until the loop pulls values through.

fn main() { let nums = vec![1, 2, 3]; let it = nums.iter().map(|x| x * 2); println!("built, nothing ran yet"); for n in it { println!("{}", n); } }

Laziness lets long chains fuse into one pass with no middle storage. Infinite iterators stay safe too, since only requested items compute. Remember that an unused plan does nothing at all.

Collect results

Collect drains an iterator into a container such as a vector. The target type rarely needs naming because the next use reveals it. Words below gathers each number turned string into one growable list.

fn main() { let nums = vec![1, 2, 3]; let words: Vec<String> = nums.iter().map(|n| n.to_string()).collect(); println!("{:?}", words); }

The annotation pins the container when inference needs help, and turbofish works too. Strings, sets, and maps all collect from matching iterators. Collect is the standard bridge back to owned data.

Find fold any

Consumers finish the job in one value instead of another iterator. Find returns the first match, sum totals everything, and any reports whether some item passes. Found holds an option because the search may come up empty.

fn main() { let nums = vec![1, 2, 3, 4]; let found = nums.iter().find(|x| *x == 3); let sum: i32 = nums.iter().sum(); let big = nums.iter().any(|x| *x > 10); println!("{:?} {} {}", found, sum, big); }

Fold generalizes sum with a starting value and a combining closure. Find borrows the match instead of copying it out. Scan the Iterator docs for the rest, since dozens of small consumers await there.

Next: Smart pointers

Article author: Arthur Isaev

Related articles
Rust
Rust course: zero to hero in 50 lessons
What is Rust and where it runs
Install Rust
cargo new
Your first program
Variables
Numbers
Strings
Booleans
Tuples
Arrays
Vectors
Slices
if and else
match
Loops
Ownership
Borrowing
Lifetimes
Functions
Structs
Enums in Rust
Advanced match in Rust
Option combinators in Rust
Result and the question mark in Rust
Advanced strings in Rust
Vec methods in Rust
HashMaps in Rust
Modules in Rust
Crates and workspaces in Rust
Testing in Rust
Error handling
Traits
Generics
Trait bounds
Closures
Iterators
Smart pointers
Threads
Mutex and Arc
Files
CLI arguments
Environment variables
Diagnostics
Time
Parsing strings
TCP networking
Capstone: wordfreq CLI
Capstone: tiny HTTP server
Modern Rust tour
Hero roadmap: the whole course on one page
Install Rust on Windows 11
Install Rust on Ubuntu
Install Rust on Rocky Linux
Install Rust on macOS
Install Rust on FreeBSD
Rust in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: