Rust
Closure and iterator
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"]
Exercise 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.
Show example 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);
}
Test yourself
-
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
Show answer
filter gives &Item to look at the element without consuming it — filter only looks at the element to keep or drop it, so it borrows. Combined with .iter() it becomes &&i32.
-
Filter by a criterion
let gecen: Vec<i32> = notlar.iter().copied().____(|&n| n >= esik).collect();
Show answer
let gecen: Vec<i32> = notlar.iter().copied().filter(|&n| n >= esik).collect();
-
Method and closure role
- map(|x| ..)
- Transforms
- filter(|x| ..)
- Filters
- find(|x| ..)
- First match
- any(|x| ..)
- At least one?
Next lesson: Summary - Closures