Rust Closures

Example

Case: Hello

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fn main() {
// Increment via closures and functions.
fn function(i: i32) -> i32 { i + 1 }

// Closures are anonymous, here we are binding them to references
// Annotation is identical to function annotation but is optional
// as are the `{}` wrapping the body. These nameless functions
// are assigned to appropriately named variables.
let closure_annotated = |i: i32| -> i32 { i + 1 };
let closure_inferred = |i| i + 1;

let i = 1;
// Call the function and closures.
println!("function: {}", function(i));
println!("closure_annotated: {}", closure_annotated(i));
println!("closure_inferred: {}", closure_inferred(i));

// A closure taking no arguments which returns an `i32`.
// The return type is inferred(推断的).
let one = || 1;
println!("closure returning one: {}", one());
}
1
2
3
4
function: 2
closure_annotated: 2
closure_inferred: 2
closure returning one: 1

Case 2

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
fn main() {
use std::mem;

let color = "green";

// A closure to print `color` which immediately borrows (`&`)
// `color` and stores the borrow and closure in the `print`
// variable. It will remain borrowed until `print` goes out of
// scope. `println!` only requires `by reference` so it doesn't
// impose anything more restrictive.
let print = || println!("`color`: {}", color);

// Call the closure using the borrow.
print();
print();

let mut count = 0;

// A closure to increment `count` could take either `&mut count`
// or `count` but `&mut count` is less restrictive so it takes
// that. Immediately borrows `count`.
//
// A `mut` is required on `inc` because a `&mut` is stored inside.
// Thus, calling the closure mutates the closure which requires
// a `mut`.
let mut inc = || {
count += 1;
println!("`count`: {}", count);
};

// Call the closure.
inc();
inc();
// count = 10; error[E0506]: cannot assign to `count` because it is borrowed
// println!("return count and change {}", count);

//let _reborrow = &mut count;
// ^ TODO: try uncommenting this line.

// A non-copy type.
let movable = Box::new(3);

// `mem::drop` requires `T` so this must take by value. A copy type
// would copy into the closure leaving the original untouched.
// A non-copy must move and so `movable` immediately moves into
// the closure.
let consume = || {
println!("`movable`: {:?}", movable);
mem::drop(movable);
};

// `consume` consumes the variable so this can only be called once.
consume();
//consume();
// ^ TODO: Try uncommenting this line.
}
1
2
3
4
5
`color`: green
`color`: green
`count`: 1
`count`: 2
`movable`: 3