summaryrefslogtreecommitdiffstats
path: root/src/doc/rust-by-example/src/fn/closures/anonymity.md
diff options
context:
space:
mode:
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.md56
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/