Skip to content

Commit 4a7c70e

Browse files
authored
Merge pull request #1265 from andymac-2/closures-capturing
Capturing changes
2 parents 9c9c4d5 + eac3fdf commit 4a7c70e

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

src/fn/closures/capture.md

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,51 @@ fn main() {
1818
1919
let color = "green";
2020
21-
// A closure to print `color` which immediately borrows (`&`)
22-
// `color` and stores the borrow and closure in the `print`
23-
// variable. It will remain borrowed until `print` goes out of
24-
// scope. `println!` only requires `by reference` so it doesn't
21+
// A closure to print `color` which immediately borrows (`&`) `color` and
22+
// stores the borrow and closure in the `print` variable. It will remain
23+
// borrowed until `print` is used the last time.
24+
//
25+
// `println!` only requires arguments by immutable reference so it doesn't
2526
// impose anything more restrictive.
2627
let print = || println!("`color`: {}", color);
2728
2829
// Call the closure using the borrow.
2930
print();
31+
32+
// `color` can be borrowed immutably again, because the closure only holds
33+
// an immutable reference to `color`.
34+
let _reborrow = &color;
3035
print();
3136
32-
let mut count = 0;
37+
// A move or reborrow is allowed after the final use of `print`
38+
let _color_moved = color;
3339
34-
// A closure to increment `count` could take either `&mut count`
35-
// or `count` but `&mut count` is less restrictive so it takes
36-
// that. Immediately borrows `count`.
40+
41+
let mut count = 0;
42+
// A closure to increment `count` could take either `&mut count` or `count`
43+
// but `&mut count` is less restrictive so it takes that. Immediately
44+
// borrows `count`.
3745
//
38-
// A `mut` is required on `inc` because a `&mut` is stored inside.
39-
// Thus, calling the closure mutates the closure which requires
40-
// a `mut`.
46+
// A `mut` is required on `inc` because a `&mut` is stored inside. Thus,
47+
// calling the closure mutates the closure which requires a `mut`.
4148
let mut inc = || {
4249
count += 1;
4350
println!("`count`: {}", count);
4451
};
4552
46-
// Call the closure.
47-
inc();
53+
// Call the closure using a mutable borrow.
4854
inc();
4955
50-
//let _reborrow = &mut count;
56+
// The closure still mutably borrows `count` because it is called later.
57+
// An attempt to reborrow will lead to an error.
58+
// let _reborrow = &count;
5159
// ^ TODO: try uncommenting this line.
60+
inc();
61+
62+
// The closure no longer needs to borrow `&mut count`. Therefore, it is
63+
// possible to reborrow without an error
64+
let _count_reborrowed = &mut count;
65+
5266
5367
// A non-copy type.
5468
let movable = Box::new(3);
@@ -64,7 +78,7 @@ fn main() {
6478
6579
// `consume` consumes the variable so this can only be called once.
6680
consume();
67-
//consume();
81+
// consume();
6882
// ^ TODO: Try uncommenting this line.
6983
}
7084
```
@@ -82,7 +96,7 @@ fn main() {
8296
println!("{}", contains(&1));
8397
println!("{}", contains(&4));
8498
85-
// `println!("There're {} elements in vec", haystack.len());`
99+
// println!("There're {} elements in vec", haystack.len());
86100
// ^ Uncommenting above line will result in compile-time error
87101
// because borrow checker doesn't allow re-using variable after it
88102
// has been moved.

0 commit comments

Comments
 (0)