Closure and iterator
- Rust course
- Intermediate
- Lesson 46/115
- 4 min
Use closures with iterator methods.
Closures and iterators
The most common use of closures is iterator methods. Since a closure can capture values from its environment, the criteria can be given from outside:
let esik = 50;
let notlar = vec![45, 72, 90, 38, 66];
let gecen: Vec<i32> = notlar
.iter()
.copied()
.filter(|&n| n >= esik) // esik was captured
.collect();
println!("{:?}", gecen); // [72, 90, 66]copied() turns &i32 elements into i32, so the following closures don't deal with double references.
Passing a function directly
Instead of a closure, a named function or method can be passed too; this shortens the code:
fn cift_mi(n: &i32) -> bool { n % 2 == 0 }
let v = vec![1, 2, 3, 4];
let ciftler: Vec<&i32> = v.iter().filter(|n| cift_mi(n)).collect();
let metinler: Vec<String> = v.iter().map(ToString::to_string).collect();
println!("{:?} {:?}", ciftler, metinler); // [2, 4] ["1", "2", "3", "4"]Practice Passing grades
For let esik = 50; and vec![45, 72, 90, 38, 66], collect the grades passing the threshold with filter. Then build a second vector with a map adding 5 to each. Print both vectors separated by a space.
Starter code
fn main() {
// buraya yaz
}Sample solution
fn main() {
let esik = 50;
let notlar = vec![45, 72, 90, 38, 66];
let gecen: Vec<i32> = notlar.iter().copied().filter(|&n| n >= esik).collect();
let artirilmis: Vec<i32> = gecen.iter().map(|n| n + 5).collect();
println!("{:?} {:?}", gecen, artirilmis);
}Expected output
[72, 90, 66] [77, 95, 71]
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Inside <code>.filter(|n| *n > 2)</code>, why is <code>n</code> a reference?
- All closure parameters are references
- It's a bug
- Only for i32
- filter gives &Item to look at the element without consuming it Correct answer
Explanation: filter only looks at the element to keep or drop it, so it borrows. Combined with .iter() it becomes &&i32.
2 Filter by a criterion
let gecen: Vec<i32> = notlar.iter().copied().____(|&n| n >= esik).collect();
let gecen: Vec<i32> = notlar.iter().copied().filter(|&n| n >= esik).collect();
Explanation: filter keeps the elements for which the closure returns true.
3 Method and closure role
| Term | Meaning |
|---|---|
map(|x| ..) |
Transforms |
filter(|x| ..) |
Filters |
find(|x| ..) |
First match |
any(|x| ..) |
At least one? |