闭包(closure)
大约 2 分钟
闭包(closure)
概念
Rust 中的 闭包(closure),也叫做 lambda 表达式 或者 lambda,是一类能够捕获周围作用域中变量的函数。
调用一个闭包和调用一个函数完全相同,不过调用闭包时,输入和返回类型两者都可以自动推导,而输入变量名必须指明。
与普通函数的区别:
- 声明时使用
||
替代()
将输入参数括起来,去掉了fn
关键字和函数名。 - 函数体定界符({})对于单个表达式是可选的,其他情况必须加上。
- 有能力捕获外部环境的变量
定义闭包
// 普通函数
fn 函数名(参数列表) -> 返回值 {
// 业务逻辑
}
// 闭包 // 去掉了 fn,去掉了函数名,用`||`代替`()`
|参数列表| {
// 业务逻辑
}
// 无参数闭包
|| {
// 业务逻辑
}
闭包也可以赋值给一个变量,可以通过调用这个变量来完成闭包的调用
let 闭包变量 = |参数列表| {
// 闭包的具体逻辑
}
示例:
let add = |a, b| { a + b };
let x = add(2, 4);
println!("{}", x); // 输出 6,= 2+4
let double = |x| { x * 2 };
let y = double(5);
println!("{}", y); // 输出10,= 5*2
let v = 3;
let add2 = |x| { v + x }; // 这里说明闭包有能力"捕获外部环境的变量",虽然这里只是捕获了栈变量,不设计所有权的移动和借用
println!("{}", add2(4)); // 输出7,3+4
捕获
闭包本质上很灵活,闭包可以在没有类型标注的情况下运行。可移动(move),又可借用(borrow)。闭包可以通过以下方式捕获变量:
- 通过引用:&T
- 通过可变引用:&mut T
- 通过值:T
总结
闭包就是在一个函数内创建立即调用的另一个函数。
闭包是一个匿名函数。
闭包虽然没有函数名,但可以把整个闭包赋值一个变量,通过调用该变量来完成闭包的调用。
闭包不用声明返回值,但它却可以有返回值。并且使用最后一条语句的执行结果作为返回值。闭包的返回值可以赋值给变量。
闭包又称之为 内联函数。可以让闭包访问外层函数里的变量。