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
@@ -2200,6 +2267,35 @@ impl<'a, T: ?Sized> DerefMut for &'a mut T {
2200
2267
}
2201
2268
2202
2269
/// A version of the call operator that takes an immutable receiver.
2270
+ ///
2271
+ /// # Examples
2272
+ ///
2273
+ /// Closures automatically implement this trait, which allows them to be
2274
+ /// invoked. Note, however, that `Fn` takes an immutable reference to any
2275
+ /// captured variables. To take a mutable capture, implement [`FnMut`], and to
2276
+ /// consume the capture, implement [`FnOnce`].
2277
+ ///
2278
+ /// [`FnMut`]: trait.FnMut.html
2279
+ /// [`FnOnce`]: trait.FnOnce.html
2280
+ ///
2281
+ /// ```
2282
+ /// let square = |x| x * x;
2283
+ /// assert_eq!(square(5), 25);
2284
+ /// ```
2285
+ ///
2286
+ /// Closures can also be passed to higher-level functions through a `Fn`
2287
+ /// parameter (or a `FnMut` or `FnOnce` parameter, which are supertraits of
2288
+ /// `Fn`).
2289
+ ///
2290
+ /// ```
2291
+ /// fn call_with_one<F>(func: F) -> usize
2292
+ /// where F: Fn(usize) -> usize {
2293
+ /// func(1)
2294
+ /// }
2295
+ ///
2296
+ /// let double = |x| x * 2;
2297
+ /// assert_eq!(call_with_one(double), 2);
2298
+ /// ```
2203
2299
#[ lang = "fn" ]
2204
2300
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2205
2301
#[ rustc_paren_sugar]
@@ -2211,6 +2307,40 @@ pub trait Fn<Args> : FnMut<Args> {
2211
2307
}
2212
2308
2213
2309
/// A version of the call operator that takes a mutable receiver.
2310
+ ///
2311
+ /// # Examples
2312
+ ///
2313
+ /// Closures that mutably capture variables automatically implement this trait,
2314
+ /// which allows them to be invoked.
2315
+ ///
2316
+ /// ```
2317
+ /// let mut x = 5;
2318
+ /// {
2319
+ /// let mut square_x = || x *= x;
2320
+ /// square_x();
2321
+ /// }
2322
+ /// assert_eq!(x, 25);
2323
+ /// ```
2324
+ ///
2325
+ /// Closures can also be passed to higher-level functions through a `FnMut`
2326
+ /// parameter (or a `FnOnce` parameter, which is a supertrait of `FnMut`).
2327
+ ///
2328
+ /// ```
2329
+ /// fn do_twice<F>(mut func: F)
2330
+ /// where F: FnMut()
2331
+ /// {
2332
+ /// func();
2333
+ /// func();
2334
+ /// }
2335
+ ///
2336
+ /// let mut x: usize = 1;
2337
+ /// {
2338
+ /// let add_two_to_x = || x += 2;
2339
+ /// do_twice(add_two_to_x);
2340
+ /// }
2341
+ ///
2342
+ /// assert_eq!(x, 5);
2343
+ /// ```
2214
2344
#[ lang = "fn_mut" ]
2215
2345
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2216
2346
#[ rustc_paren_sugar]
@@ -2222,6 +2352,41 @@ pub trait FnMut<Args> : FnOnce<Args> {
2222
2352
}
2223
2353
2224
2354
/// A version of the call operator that takes a by-value receiver.
2355
+ ///
2356
+ /// # Examples
2357
+ ///
2358
+ /// By-value closures automatically implement this trait, which allows them to
2359
+ /// be invoked.
2360
+ ///
2361
+ /// ```
2362
+ /// let x = 5;
2363
+ /// let square_x = move || x * x;
2364
+ /// assert_eq!(square_x(), 25);
2365
+ /// ```
2366
+ ///
2367
+ /// By-value Closures can also be passed to higher-level functions through a
2368
+ /// `FnOnce` parameter.
2369
+ ///
2370
+ /// ```
2371
+ /// fn consume_with_relish<F>(func: F)
2372
+ /// where F: FnOnce() -> String
2373
+ /// {
2374
+ /// // `func` consumes its captured variables, so it cannot be run more
2375
+ /// // than once
2376
+ /// println!("Consumed: {}", func());
2377
+ ///
2378
+ /// println!("Delicious!");
2379
+ ///
2380
+ /// // Attempting to invoke `func()` again will throw a `use of moved
2381
+ /// // value` error for `func`
2382
+ /// }
2383
+ ///
2384
+ /// let x = String::from("x");
2385
+ /// let consume_and_return_x = move || x;
2386
+ /// consume_with_relish(consume_and_return_x);
2387
+ ///
2388
+ /// // `consume_and_return_x` can no longer be invoked at this point
2389
+ /// ```
2225
2390
#[ lang = "fn_once" ]
2226
2391
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2227
2392
#[ rustc_paren_sugar]
0 commit comments