闭包
闭包是可以捕获周围环境的函数。例如,下面是一个捕获变量 x
的闭包:
|val| val + x
闭包的语法和功能使其非常适合即时使用。调用闭包与调用函数完全相同。不过,闭包的输入和返回类型可以被推断,而输入变量名必须指定。
闭包的其他特点包括:
- 使用
||
而不是()
来包围输入变量。 - 单行表达式可省略函数体定界符(
{}
),其他情况则必须使用 - 能够捕获外部环境的变量
fn main() { let outer_var = 42; // 常规函数无法引用外部环境的变量 //fn function(i: i32) -> i32 { i + outer_var } // TODO:取消上面这行的注释,查看编译器错误 // 编译器会建议我们定义一个闭包来替代 // 闭包是匿名的,这里我们将它们绑定到引用 // 注解与函数注解相同,但是可选的 // 包裹函数体的 `{}` 也是可选的 // 这些无名函数被赋值给适当命名的变量 let closure_annotated = |i: i32| -> i32 { i + outer_var }; let closure_inferred = |i | i + outer_var ; // 调用闭包 println!("closure_annotated:{}", closure_annotated(1)); println!("closure_inferred:{}", closure_inferred(1)); // 闭包类型一旦被推断,就不能再用其他类型重新推断。 //println!("不能用其他类型重用 closure_inferred:{}", closure_inferred(42i64)); // TODO:取消上面这行的注释,观察编译器错误。 // 一个无参数并返回 `i32` 的闭包。 // 返回类型是推断的。 let one = || 1; println!("返回 1 的闭包:{}", one()); }