Iterators and Closures in Rust
Iterators are how idiomatic Rust processes collections. They read like a pipeline and compile down to code as fast as a hand-written loop.
The basics
let prices = vec![499, 1299, 250, 3999];
let affordable: Vec<u32> = prices
.iter() // borrow each item
.filter(|&&p| p < 1500)
.map(|p| p * 90 / 100) // 10% off
.collect();
let total: u32 = prices.iter().sum();
let max = prices.iter().max(); // Option<&u32>
let any_expensive = prices.iter().any(|&p| p > 3000);
iter, iter_mut and into_iter
.iter()- yields&T; the collection is still usable afterwards..iter_mut()- yields&mut T; change items in place..into_iter()- yieldsT; consumes the collection.
collect into many types
use std::collections::{HashMap, HashSet};
let words = ["rust", "go", "rust", "zig"];
let unique: HashSet<&str> = words.iter().copied().collect();
let lengths: HashMap<&str, usize> = words.iter().map(|w| (*w, w.len())).collect();
// Collecting Results: stops at the first error
let numbers: Result<Vec<i32>, _> = ["1", "2", "x"].iter().map(|s| s.parse::<i32>()).collect();
More useful adapters
for (i, name) in names.iter().enumerate() { println!("{i}: {name}"); }
let pairs: Vec<_> = names.iter().zip(scores.iter()).collect();
let first_three: Vec<_> = items.iter().take(3).collect();
let total_len = names.iter().fold(0, |acc, n| acc + n.len());
let chunks: Vec<&[u8]> = bytes.chunks(4).collect();
Closures capture their environment
let min_age = 18;
let adults: Vec<_> = people.iter().filter(|p| p.age >= min_age).collect(); // borrows min_age
let mut count = 0;
let mut increment = || count += 1; // FnMut: mutates captured state
increment();
let name = String::from("job-1");
let task = move || println!("running {name}"); // move: takes ownership (needed for threads)
Functions that accept closures use Fn (read only), FnMut (mutates captures) or FnOnce (consumes captures, callable once). Pick the least restrictive bound that works for your use.
Was this article helpful?
Comments
No comments yet. Have a question or a tip? Be the first to share it.