3 Closures are inherently flexible and will do what the functionality requires
4 to make the closure work without annotation. This allows capturing to
5 flexibly adapt to the use case, sometimes moving and sometimes borrowing.
6 Closures can capture variables:
9 * by mutable reference: `&mut T`
12 They preferentially capture variables by reference and only go lower when
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
25 // impose anything more restrictive.
26 let print = || println!("`color`: {}", color);
28 // Call the closure using the borrow.
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`.
38 // A `mut` is required on `inc` because a `&mut` is stored inside.
39 // Thus, calling the closure mutates the closure which requires
43 println!("`count`: {}", count);
50 //let _reborrow = &mut count;
51 // ^ TODO: try uncommenting this line.
54 let movable = Box::new(3);
56 // `mem::drop` requires `T` so this must take by value. A copy type
57 // would copy into the closure leaving the original untouched.
58 // A non-copy must move and so `movable` immediately moves into
61 println!("`movable`: {:?}", movable);
65 // `consume` consumes the variable so this can only be called once.
68 // ^ TODO: Try uncommenting this line.
72 Using `move` before vertical pipes forces closure
73 to take ownership of captured variables:
77 // `Vec` has non-copy semantics.
78 let haystack = vec![1, 2, 3];
80 let contains = move |needle| haystack.contains(needle);
82 println!("{}", contains(&1));
83 println!("{}", contains(&4));
85 // `println!("There're {} elements in vec", haystack.len());`
86 // ^ Uncommenting above line will result in compile-time error
87 // because borrow checker doesn't allow re-using variable after it
90 // Removing `move` from closure's signature will cause closure
91 // to borrow _haystack_ variable immutably, hence _haystack_ is still
92 // available and uncommenting above line will not cause an error.
98 [`Box`][box] and [`std::mem::drop`][drop]
100 [box]: ../../std/box.md
101 [drop]: https://doc.rust-lang.org/std/mem/fn.drop.html