类型匿名

闭包可以简洁地捕获来自封闭作用域的变量。这有什么后果吗?当然有。请注意,将闭包用作函数参数需要使用泛型,这是因为它们的定义方式

#![allow(unused)]
fn main() {
// `F` must be generic.
fn apply<F>(f: F) where
    F: FnOnce() {
    f();
}
}

定义闭包时,编译器会隐式创建一个新的匿名结构来存储捕获的变量,同时通过 FnFnMutFnOnce 这三种特征之一为这个未知类型实现功能。此类型将分配给存储到调用前的变量。

由于此新类型是未知类型,因此在函数中使用它需要泛型。但是,无界类型参数 <T> 仍然不明确,因此不允许使用。因此,通过 FnFnMutFnOnce(它实现的)特征之一进行绑定足以指定其类型。

// `F` must implement `Fn` for a closure which takes no
// inputs and returns nothing - exactly what is required
// for `print`.
fn apply<F>(f: F) where
    F: Fn() {
    f();
}

fn main() {
    let x = 7;

    // Capture `x` into an anonymous type and implement
    // `Fn` for it. Store it in `print`.
    let print = || println!("{}", x);

    apply(print);
}

另请参阅

深入分析FnFnMutFnOnce