作为输入参数
Rust 通常能自动选择如何捕获变量,无需类型标注。但在编写函数时,这种模糊性是不允许的。当将闭包作为输入参数时,必须使用特定的 trait
来注解闭包的完整类型。这些 trait 由闭包对捕获值的处理方式决定。按限制程度从高到低排列如下:
Fn
:闭包通过引用使用捕获的值(&T
)FnMut
:闭包通过可变引用使用捕获的值(&mut T
)FnOnce
:闭包通过值使用捕获的值(T
)
编译器会以尽可能最少限制的方式逐个捕获变量。
例如,考虑一个注解为 FnOnce
的参数。这表示闭包可能通过 &T
、&mut T
或 T
进行捕获,但编译器最终会根据捕获变量在闭包中的使用方式来决定。
这是因为如果可以移动,那么任何类型的借用也应该是可能的。注意反过来并不成立。如果参数被注解为 Fn
,那么通过 &mut T
或 T
捕获变量是不允许的。但 &T
是允许的。
在下面的例子中,尝试交换 Fn
、FnMut
和 FnOnce
的用法,看看会发生什么: