## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# 类型匿名

闭包能简洁地从外部作用域捕获变量。这会有什么影响吗？当然会有。注意观察如何将闭包作为函数参数使用时需要泛型，这是由于闭包的定义方式所决定的：

    #![allow(unused)]
    fn main() {
    // `F` 必须是泛型
    fn apply<F>(f: F) where
        F: FnOnce() {
        f();
    }
    }

当定义一个闭包时，编译器会隐式创建一个新的匿名结构来存储内部捕获的变量，同时通过 `Fn`、`FnMut` 或 `FnOnce` 这些 `trait` 之一为这个未知类型实现功能。这个类型被赋给变量并存储，直到被调用。

由于这个新类型是未知类型，在函数中使用时就需要泛型。然而，一个无界的类型参数 `<T>` 仍然会是模糊的，不被允许。因此，通过 `Fn`、`FnMut` 或 `FnOnce` 这些 `trait` 之一（它实现的）来约束就足以指定其类型。

    // `F` 必须实现 `Fn` 用于一个不接受输入且不返回任何内容的闭包
    // - 这正是 `print` 所需要的
    fn apply<F>(f: F) where
        F: Fn() {
        f();
    }

    fn main() {
        let x = 7;

        // 将 `x` 捕获到一个匿名类型中并为其实现 `Fn`
        // 将其存储在 `print` 中
        let print = || println!("{}", x);

        apply(print);
    }

### 另请参阅：

深入分析、`Fn`、`FnMut` 和 `FnOnce`