-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathlambdas_closures.alu
76 lines (63 loc) · 1.91 KB
/
lambdas_closures.alu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use std::range::Range;
use std::collections::Vector;
fn is_prime(v: i64) -> bool {
let i: i64 = 2;
while i < v {
if v % i == 0 {
return false;
}
i += 1;
}
true
}
fn print_filtered<F: Fn(i64) -> bool>(range: Range<i64>, filter: F) {
let first = true;
for i in range {
if filter(i) {
if first {
print!("{}", i);
first = false;
} else {
print!(", {}", i)
}
}
}
println!("");
}
fn main() {
// Anonymous functions that do not capture ambient variables
let hw = || { println!("Hello, world!"); };
hw();
hw();
print_filtered(1..100, |p: i64| -> bool { p < 10 });
print_filtered(1..100, |p: i64| -> bool { is_prime(p) });
// Anonymous functions can be coerced to function pointers.
let hw_ptr: fn() = hw;
hw_ptr();
// Closures are anonymous functions that capture variables from ambient scope.
// Captures can be either by value (`=capture`) or by reference (`&capture`) and
// they need to be explicitly specified in the function signature.
// `a` is passed by value (is copied) into the closure. Captured values are part of the
// closure's state and can be mutated, but the original variable remains unchanged.
let a = 1i64;
let f = |=a, increment: i64| {
a += increment;
println!("[inside] a = {}", a)
};
f(10);
f(1);
println!("[outside] a = {}", a);
// `composites` is passed by reference. The changes will be reflected in the original
// variable.
let composites: Vector<i64> = Vector::new();
defer composites.free();
print_filtered(1..100, |&composites, p: i64| -> bool {
if is_prime(p) {
true
} else {
composites.push(p);
false
}
});
println!("composites.len() = {}", composites.len());
}