1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/// 采用不可变接收者的调用运算符的版本。
///
/// `Fn` 的实例可以在不改变状态的情况下重复调用。
///
/// *请勿将此 trait (`Fn`) 与 [function pointers] (`fn`) 混淆。*
///
/// `Fn` 由闭包自动实现,闭包只对捕获的变量进行不可变引用或根本不捕获任何内容,还有 (安全) [function pointers] (有一些警告,请参见其文档以获取更多详细信息)。
///
/// 此外,对于实现 `Fn` 的任何类型 `F`,`&F` 也实现了 `Fn`。
///
/// 由于 [`FnMut`] 和 [`FnOnce`] 都是 `Fn` 的 supertraits,因此 `Fn` 的任何实例都可以用作参数,其中需要 [`FnMut`] 或 [`FnOnce`]。
///
/// 当您要接受类似函数类型的参数并且需要反复调用且不改变状态 (例如,同时调用它) 时,请使用 `Fn` 作为绑定。
/// 如果不需要严格的要求,请使用 [`FnMut`] 或 [`FnOnce`] 作为界限。
///
/// 有关此主题的更多信息,请参见 [Rust 编程语言][book] 中关于闭包的章节。
///
/// 还要注意的是 `Fn` traits 的特殊语法 (例如
/// `Fn(usize, bool) -> usize`)。对此技术细节感兴趣的人可以参考 [Rustonomicon 中的相关部分][nomicon]。
///
/// [book]: ../../book/ch13-01-closures.html
/// [function pointers]: fn
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## 调用一个闭包
///
/// ```
/// let square = |x| x * x;
/// assert_eq!(square(5), 25);
/// ```
///
/// ## 使用 `Fn` 参数
///
/// ```
/// fn call_with_one<F>(func: F) -> usize
///     where F: Fn(usize) -> usize {
///     func(1)
/// }
///
/// let double = |x| x * 2;
/// assert_eq!(call_with_one(double), 2);
/// ```
///
///
///
///
///
///
///
///
///
#[lang = "fn"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
    label = "expected an `Fn<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // 这样 regex 可以依靠 `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait Fn<Args>: FnMut<Args> {
    /// 执行调用操作。
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}

/// 采用可变接收者的调用运算符的版本。
///
/// `FnMut` 的实例可以重复调用,并且可以改变状态。
///
/// `FnMut` 由闭包自动实现,闭包将可变引用引用到捕获的变量,以及实现 [`Fn`] 的所有类型,例如 (safe) [function pointers] (因为 `FnMut` 是 [`Fn`] 的特征)。
/// 另外,对于任何实现 `FnMut` 的 `F` 类型,`&mut F` 也实现 `FnMut`。
///
/// 由于 [`FnOnce`] 是 `FnMut` 的 super trait,因此可以在期望 [`FnOnce`] 的地方使用 `FnMut` 的任何实例,并且由于 [`Fn`] 是 `FnMut` 的子特性,因此可以在预期 `FnMut` 的地方使用 [`Fn`] 的任何实例。
///
/// 当您想接受类似函数类型的参数并需要反复调用它,同时允许其改变状态时,请使用 `FnMut` 作为绑定。
/// 如果您不希望参数改变状态,请使用 [`Fn`] 作为绑定; 如果不需要重复调用,请使用 [`FnOnce`]。
///
/// 有关此主题的更多信息,请参见 [Rust 编程语言][book] 中关于闭包的章节。
///
/// 还要注意的是 `Fn` traits 的特殊语法 (例如
/// `Fn(usize, bool) -> usize`)。对此技术细节感兴趣的人可以参考 [Rustonomicon 中的相关部分][nomicon]。
///
/// [book]: ../../book/ch13-01-closures.html
/// [function pointers]: fn
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## 调用可变捕获闭包
///
/// ```
/// let mut x = 5;
/// {
///     let mut square_x = || x *= x;
///     square_x();
/// }
/// assert_eq!(x, 25);
/// ```
///
/// ## 使用 `FnMut` 参数
///
/// ```
/// fn do_twice<F>(mut func: F)
///     where F: FnMut()
/// {
///     func();
///     func();
/// }
///
/// let mut x: usize = 1;
/// {
///     let add_two_to_x = || x += 2;
///     do_twice(add_two_to_x);
/// }
///
/// assert_eq!(x, 5);
/// ```
///
///
///
///
///
///
///
///
///
#[lang = "fn_mut"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
    label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // 这样 regex 可以依靠 `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait FnMut<Args>: FnOnce<Args> {
    /// 执行调用操作。
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

/// 具有按值接收者的调用运算符的版本。
///
/// 可以调用 `FnOnce` 的实例,但可能无法多次调用。因此,如果唯一知道类型的是它实现 `FnOnce`,则只能调用一次。
///
/// `FnOnce` 由可能消耗捕获变量的闭包以及实现 [`FnMut`] 的所有类型 (例如 (safe) [function pointers] (因为 `FnOnce` 是 [`FnMut`] 的特征) ) 自动实现。
///
///
/// 由于 [`Fn`] 和 [`FnMut`] 都是 `FnOnce` 的子特性,因此可以在期望使用 `FnOnce` 的情况下使用 [`Fn`] 或 [`FnMut`] 的任何实例。
///
/// 当您想接受类似函数类型的参数并且只需要调用一次时,可以使用 `FnOnce` 作为绑定。
/// 如果需要重复调用该参数,请使用 [`FnMut`] 作为界限; 如果还需要它不改变状态,请使用 [`Fn`]。
///
/// 有关此主题的更多信息,请参见 [Rust 编程语言][book] 中关于闭包的章节。
///
/// 还要注意的是 `Fn` traits 的特殊语法 (例如
/// `Fn(usize, bool) -> usize`)。对此技术细节感兴趣的人可以参考 [Rustonomicon 中的相关部分][nomicon]。
///
/// [book]: ../../book/ch13-01-closures.html
/// [function pointers]: fn
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## 使用 `FnOnce` 参数
///
/// ```
/// fn consume_with_relish<F>(func: F)
///     where F: FnOnce() -> String
/// {
///     // `func` 使用其捕获的变量,因此不能多次运行。
/////
///     println!("Consumed: {}", func());
///
///     println!("Delicious!");
///
///     // 再次尝试调用 `func()` 将为 `func` 引发 `use of moved value` 错误。
/////
/// }
///
/// let x = String::from("x");
/// let consume_and_return_x = move || x;
/// consume_with_relish(consume_and_return_x);
///
/// // `consume_and_return_x` 现在不能再被调用
/// ```
///
///
///
///
///
///
///
///
#[lang = "fn_once"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
    label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // 这样 regex 可以依靠 `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait FnOnce<Args> {
    /// 使用调用运算符后的返回类型。
    #[lang = "fn_once_output"]
    #[stable(feature = "fn_once_output", since = "1.12.0")]
    type Output;

    /// 执行调用操作。
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

mod impls {
    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> Fn<A> for &F
    where
        F: Fn<A>,
    {
        extern "rust-call" fn call(&self, args: A) -> F::Output {
            (**self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnMut<A> for &F
    where
        F: Fn<A>,
    {
        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
            (**self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnOnce<A> for &F
    where
        F: Fn<A>,
    {
        type Output = F::Output;

        extern "rust-call" fn call_once(self, args: A) -> F::Output {
            (*self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnMut<A> for &mut F
    where
        F: FnMut<A>,
    {
        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
            (*self).call_mut(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnOnce<A> for &mut F
    where
        F: FnMut<A>,
    {
        type Output = F::Output;
        extern "rust-call" fn call_once(self, args: A) -> F::Output {
            (*self).call_mut(args)
        }
    }
}