Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capturing changes #1265

Merged
merged 3 commits into from
Sep 20, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions src/fn/closures/capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,51 @@ fn main() {

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
// 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` is used the last time.
//
// `println!` only requires arguments by immutable reference so it doesn't
// impose anything more restrictive.
let print = || println!("`color`: {}", color);

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

// `color` can be borrowed immutably again, because the closure only holds
// an immutable reference to `color`.
let _reborrow = &color;
print();

let mut count = 0;
// A move or reborrow is allowed after the final use of `print`
let _color_moved = color;

// 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`.

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`.
// 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();
// Call the closure using a mutable borrow.
inc();

//let _reborrow = &mut count;
// The closure still mutably borrows `count` because it is called later.
// An attempt to reborrow will lead to an error.
// let _reborrow = &count;
// ^ TODO: try uncommenting this line.
inc();

// The closure no longer needs to borrow `&mut count`. Therefore, it is
// possible to reborrow without an error
let _count_reborrowed = &mut count;


// A non-copy type.
let movable = Box::new(3);
Expand All @@ -64,7 +78,7 @@ fn main() {

// `consume` consumes the variable so this can only be called once.
consume();
//consume();
// consume();
// ^ TODO: Try uncommenting this line.
}
```
Expand All @@ -82,7 +96,7 @@ fn main() {
println!("{}", contains(&1));
println!("{}", contains(&4));

// `println!("There're {} elements in vec", haystack.len());`
// println!("There're {} elements in vec", haystack.len());
// ^ Uncommenting above line will result in compile-time error
// because borrow checker doesn't allow re-using variable after it
// has been moved.
Expand Down