Rust 闭包类型匿名
闭包从周围的作用域中捕获变量是简单明了的。这样会有某些后果吗?确实有。观察一下使用闭包作为函数参数,这要求闭包是泛型的,闭包定义的方式决定了这是必要的。
#![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); }
既然闭包可以作为参数,你很可能想知道函数是否也可以呢。确实可以!如果你声明一个接受闭包作为参数的函数,那么任何满足该闭包的 trait 约束的函数都可以作为其参数。// 定义一个函数,可以接受一个由 `Fn` 限定的 ...