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
|
// `unsafe` is a permission marker, not a semantic change: it does not alter
// what the enclosed operations mean, so the block is transparent and each
// operation inside still goes through the ordinary lowering.
//
// Nim's closures capture by reference, as Rust's non-`move` closures do.
fn apply(f: impl Fn(i32) -> i32, x: i32) -> i32 {
f(x)
}
fn twice(x: i32) -> i32 {
x * 2
}
fn halve(n: i32) -> Result<i32, i32> {
if n % 2 == 0 { Ok(n / 2) } else { Err(n) }
}
fn as_str(b: &[u8]) -> &str {
unsafe { core::str::from_utf8_unchecked(b) }
}
fn main() {
let add_one = |x: i32| x + 1;
println!("{}", apply(add_one, 10));
println!("{}", apply(twice, 10));
println!("{}", apply(|x: i32| x * x, 7));
// A closure capturing an enclosing binding, by reference.
let base: i32 = 100;
let shift = |x: i32| x + base;
println!("{}", apply(shift, 5));
// `.map` over a Result: the closure's parameter type comes from the
// receiver, and the error branch is carried through untouched.
println!("{:?}", halve(8).map(|v| v * 10));
println!("{:?}", halve(7).map(|v| v * 10));
// `&str` is a view of someone else's bytes, not a copy.
let bytes: Vec<u8> = vec![104, 105];
println!("{} {}", as_str(&bytes), as_str(&bytes).len());
let n: i32 = unsafe { twice(21) };
println!("{}", n);
}
|