diff options
Diffstat (limited to 'src/doc/rust-by-example/src/fn/closures/anonymity.md')
-rw-r--r-- | src/doc/rust-by-example/src/fn/closures/anonymity.md | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/doc/rust-by-example/src/fn/closures/anonymity.md b/src/doc/rust-by-example/src/fn/closures/anonymity.md new file mode 100644 index 000000000..7008a446b --- /dev/null +++ b/src/doc/rust-by-example/src/fn/closures/anonymity.md @@ -0,0 +1,56 @@ +# Type anonymity + +Closures succinctly capture variables from enclosing scopes. Does this have +any consequences? It surely does. Observe how using a closure as a function +parameter requires [generics], which is necessary because of how they are +defined: + +```rust +// `F` must be generic. +fn apply<F>(f: F) where + F: FnOnce() { + f(); +} +``` + +When a closure is defined, the compiler implicitly creates a new +anonymous structure to store the captured variables inside, meanwhile +implementing the functionality via one of the `traits`: `Fn`, `FnMut`, or +`FnOnce` for this unknown type. This type is assigned to the variable which +is stored until calling. + +Since this new type is of unknown type, any usage in a function will require +generics. However, an unbounded type parameter `<T>` would still be ambiguous +and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or +`FnOnce` (which it implements) is sufficient to specify its type. + +```rust,editable +// `F` must implement `Fn` for a closure which takes no +// inputs and returns nothing - exactly what is required +// for `print`. +fn apply<F>(f: F) where + F: Fn() { + f(); +} + +fn main() { + let x = 7; + + // Capture `x` into an anonymous type and implement + // `Fn` for it. Store it in `print`. + let print = || println!("{}", x); + + apply(print); +} +``` + +### See also: + +[A thorough analysis][thorough_analysis], [`Fn`][fn], [`FnMut`][fn_mut], +and [`FnOnce`][fn_once] + +[generics]: ../../generics.md +[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html +[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html +[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html +[thorough_analysis]: https://huonw.github.io/blog/2015/05/finding-closure-in-rust/ |