68
68
//! ```
69
69
//!
70
70
//! See the documentation for each trait for an example implementation.
71
+ //!
72
+ //! The [`Fn`], [`FnMut`], and [`FnOnce`] traits are implemented by types that can be
73
+ //! invoked like functions. Note that `Fn` takes `&self`, `FnMut` takes `&mut
74
+ //! self` and `FnOnce` takes `self`. These correspond to the three kinds of
75
+ //! methods that can be invoked on an instance: call-by-reference,
76
+ //! call-by-mutable-reference, and call-by-value. The most common use of these
77
+ //! traits is to act as bounds to higher-level functions that take functions or
78
+ //! closures as arguments.
79
+ //!
80
+ //! [`Fn`]: trait.Fn.html
81
+ //! [`FnMut`]: trait.FnMut.html
82
+ //! [`FnOnce`]: trait.FnOnce.html
83
+ //!
84
+ //! Taking a `Fn` as a parameter:
85
+ //!
86
+ //! ```rust
87
+ //! fn call_with_one<F>(func: F) -> usize
88
+ //! where F: Fn(usize) -> usize
89
+ //! {
90
+ //! func(1)
91
+ //! }
92
+ //!
93
+ //! let double = |x| x * 2;
94
+ //! assert_eq!(call_with_one(double), 2);
95
+ //! ```
96
+ //!
97
+ //! Taking a `FnMut` as a parameter:
98
+ //!
99
+ //! ```rust
100
+ //! fn do_twice<F>(mut func: F)
101
+ //! where F: FnMut()
102
+ //! {
103
+ //! func();
104
+ //! func();
105
+ //! }
106
+ //!
107
+ //! let mut x: usize = 1;
108
+ //! {
109
+ //! let add_two_to_x = || x += 2;
110
+ //! do_twice(add_two_to_x);
111
+ //! }
112
+ //!
113
+ //! assert_eq!(x, 5);
114
+ //! ```
115
+ //!
116
+ //! Taking a `FnOnce` as a parameter:
117
+ //!
118
+ //! ```rust
119
+ //! fn consume_with_relish<F>(func: F)
120
+ //! where F: FnOnce() -> String
121
+ //! {
122
+ //! // `func` consumes its captured variables, so it cannot be run more
123
+ //! // than once
124
+ //! println!("Consumed: {}", func());
125
+ //!
126
+ //! println!("Delicious!");
127
+ //!
128
+ //! // Attempting to invoke `func()` again will throw a `use of moved
129
+ //! // value` error for `func`
130
+ //! }
131
+ //!
132
+ //! let x = String::from("x");
133
+ //! let consume_and_return_x = move || x;
134
+ //! consume_with_relish(consume_and_return_x);
135
+ //!
136
+ //! // `consume_and_return_x` can no longer be invoked at this point
137
+ //! ```
71
138
72
139
#![ stable( feature = "rust1" , since = "1.0.0" ) ]
73
140
@@ -2027,6 +2094,35 @@ impl<'a, T: ?Sized> DerefMut for &'a mut T {
2027
2094
}
2028
2095
2029
2096
/// A version of the call operator that takes an immutable receiver.
2097
+ ///
2098
+ /// # Examples
2099
+ ///
2100
+ /// Closures automatically implement this trait, which allows them to be
2101
+ /// invoked. Note, however, that `Fn` takes an immutable reference to any
2102
+ /// captured variables. To take a mutable capture, implement [`FnMut`], and to
2103
+ /// consume the capture, implement [`FnOnce`].
2104
+ ///
2105
+ /// [`FnMut`]: trait.FnMut.html
2106
+ /// [`FnOnce`]: trait.FnOnce.html
2107
+ ///
2108
+ /// ```
2109
+ /// let square = |x| x * x;
2110
+ /// assert_eq!(square(5), 25);
2111
+ /// ```
2112
+ ///
2113
+ /// Closures can also be passed to higher-level functions through a `Fn`
2114
+ /// parameter (or a `FnMut` or `FnOnce` parameter, which are supertraits of
2115
+ /// `Fn`).
2116
+ ///
2117
+ /// ```
2118
+ /// fn call_with_one<F>(func: F) -> usize
2119
+ /// where F: Fn(usize) -> usize {
2120
+ /// func(1)
2121
+ /// }
2122
+ ///
2123
+ /// let double = |x| x * 2;
2124
+ /// assert_eq!(call_with_one(double), 2);
2125
+ /// ```
2030
2126
#[ lang = "fn" ]
2031
2127
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2032
2128
#[ rustc_paren_sugar]
@@ -2038,6 +2134,40 @@ pub trait Fn<Args> : FnMut<Args> {
2038
2134
}
2039
2135
2040
2136
/// A version of the call operator that takes a mutable receiver.
2137
+ ///
2138
+ /// # Examples
2139
+ ///
2140
+ /// Closures that mutably capture variables automatically implement this trait,
2141
+ /// which allows them to be invoked.
2142
+ ///
2143
+ /// ```
2144
+ /// let mut x = 5;
2145
+ /// {
2146
+ /// let mut square_x = || x *= x;
2147
+ /// square_x();
2148
+ /// }
2149
+ /// assert_eq!(x, 25);
2150
+ /// ```
2151
+ ///
2152
+ /// Closures can also be passed to higher-level functions through a `FnMut`
2153
+ /// parameter (or a `FnOnce` parameter, which is a supertrait of `FnMut`).
2154
+ ///
2155
+ /// ```
2156
+ /// fn do_twice<F>(mut func: F)
2157
+ /// where F: FnMut()
2158
+ /// {
2159
+ /// func();
2160
+ /// func();
2161
+ /// }
2162
+ ///
2163
+ /// let mut x: usize = 1;
2164
+ /// {
2165
+ /// let add_two_to_x = || x += 2;
2166
+ /// do_twice(add_two_to_x);
2167
+ /// }
2168
+ ///
2169
+ /// assert_eq!(x, 5);
2170
+ /// ```
2041
2171
#[ lang = "fn_mut" ]
2042
2172
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2043
2173
#[ rustc_paren_sugar]
@@ -2049,6 +2179,41 @@ pub trait FnMut<Args> : FnOnce<Args> {
2049
2179
}
2050
2180
2051
2181
/// A version of the call operator that takes a by-value receiver.
2182
+ ///
2183
+ /// # Examples
2184
+ ///
2185
+ /// By-value closures automatically implement this trait, which allows them to
2186
+ /// be invoked.
2187
+ ///
2188
+ /// ```
2189
+ /// let x = 5;
2190
+ /// let square_x = move || x * x;
2191
+ /// assert_eq!(square_x(), 25);
2192
+ /// ```
2193
+ ///
2194
+ /// By-value Closures can also be passed to higher-level functions through a
2195
+ /// `FnOnce` parameter.
2196
+ ///
2197
+ /// ```
2198
+ /// fn consume_with_relish<F>(func: F)
2199
+ /// where F: FnOnce() -> String
2200
+ /// {
2201
+ /// // `func` consumes its captured variables, so it cannot be run more
2202
+ /// // than once
2203
+ /// println!("Consumed: {}", func());
2204
+ ///
2205
+ /// println!("Delicious!");
2206
+ ///
2207
+ /// // Attempting to invoke `func()` again will throw a `use of moved
2208
+ /// // value` error for `func`
2209
+ /// }
2210
+ ///
2211
+ /// let x = String::from("x");
2212
+ /// let consume_and_return_x = move || x;
2213
+ /// consume_with_relish(consume_and_return_x);
2214
+ ///
2215
+ /// // `consume_and_return_x` can no longer be invoked at this point
2216
+ /// ```
2052
2217
#[ lang = "fn_once" ]
2053
2218
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2054
2219
#[ rustc_paren_sugar]
0 commit comments