]> git.proxmox.com Git - rustc.git/blob - src/doc/reference/src/expressions/closure-expr.md
New upstream version 1.49.0~beta.4+dfsg1
[rustc.git] / src / doc / reference / src / expressions / closure-expr.md
1 # Closure expressions
2
3 > **<sup>Syntax</sup>**\
4 > _ClosureExpression_ :\
5 > &nbsp;&nbsp; `move`<sup>?</sup>\
6 > &nbsp;&nbsp; ( `||` | `|` _ClosureParameters_<sup>?</sup> `|` )\
7 > &nbsp;&nbsp; ([_Expression_] | `->` [_TypeNoBounds_]&nbsp;[_BlockExpression_])
8 >
9 > _ClosureParameters_ :\
10 > &nbsp;&nbsp; _ClosureParam_ (`,` _ClosureParam_)<sup>\*</sup> `,`<sup>?</sup>
11 >
12 > _ClosureParam_ :\
13 > &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Pattern_]&nbsp;( `:` [_Type_] )<sup>?</sup>
14
15 A _closure expression_, also know as a lambda expression or a lambda, defines a
16 closure and denotes it as a value, in a single expression. A closure expression
17 is a pipe-symbol-delimited (`|`) list of irrefutable [patterns] followed by an
18 expression. Type annotations may optionally be added for the type of the
19 parameters or for the return type. If there is a return type, the expression
20 used for the body of the closure must be a normal [block]. A closure expression
21 also may begin with the `move` keyword before the initial `|`.
22
23 A closure expression denotes a function that maps a list of parameters onto
24 the expression that follows the parameters. Just like a [`let` binding], the
25 parameters are irrefutable [patterns], whose type annotation is optional and
26 will be inferred from context if not given. Each closure expression has a
27 unique, anonymous type.
28
29 Closure expressions are most useful when passing functions as arguments to other
30 functions, as an abbreviation for defining and capturing a separate function.
31
32 Significantly, closure expressions _capture their environment_, which regular
33 [function definitions] do not. Without the `move` keyword, the closure expression
34 [infers how it captures each variable from its environment](../types/closure.md#capture-modes),
35 preferring to capture by shared reference, effectively borrowing
36 all outer variables mentioned inside the closure's body. If needed the compiler
37 will infer that instead mutable references should be taken, or that the values
38 should be moved or copied (depending on their type) from the environment. A
39 closure can be forced to capture its environment by copying or moving values by
40 prefixing it with the `move` keyword. This is often used to ensure that the
41 closure's type is `'static`.
42
43 The compiler will determine which of the [closure
44 traits](../types/closure.md#call-traits-and-coercions) the closure's type will implement by how it
45 acts on its captured variables. The closure will also implement
46 [`Send`](../special-types-and-traits.md#send) and/or
47 [`Sync`](../special-types-and-traits.md#sync) if all of its captured types do.
48 These traits allow functions to accept closures using generics, even though the
49 exact types can't be named.
50
51 In this example, we define a function `ten_times` that takes a higher-order
52 function argument, and we then call it with a closure expression as an argument,
53 followed by a closure expression that moves values from its environment.
54
55 ```rust
56 fn ten_times<F>(f: F) where F: Fn(i32) {
57 for index in 0..10 {
58 f(index);
59 }
60 }
61
62 ten_times(|j| println!("hello, {}", j));
63 // With type annotations
64 ten_times(|j: i32| -> () { println!("hello, {}", j) });
65
66 let word = "konnichiwa".to_owned();
67 ten_times(move |j| println!("{}, {}", word, j));
68 ```
69
70 ## Attributes on closure parameters
71
72 Attributes on closure parameters follow the same rules and restrictions as
73 [regular function parameters].
74
75 [block]: block-expr.md
76 [function definitions]: ../items/functions.md
77 [patterns]: ../patterns.md
78 [regular function parameters]: ../items/functions.md#attributes-on-function-parameters
79
80 [_Expression_]: ../expressions.md
81 [_BlockExpression_]: block-expr.md
82 [_TypeNoBounds_]: ../types.md#type-expressions
83 [_Pattern_]: ../patterns.md
84 [_Type_]: ../types.md#type-expressions
85 [`let` binding]: ../statements.md#let-statements
86 [_OuterAttribute_]: ../attributes.md