Rust 闭包(Closure)

闭包就是在一个函数内创建立即调用的另一个函数。闭包是一个匿名函数。也就是没有函数名称。

闭包虽然没有函数名,但可以把整个闭包赋值一个变量,通过调用该变量来完成闭包的调用。从某些方面说,这个变量就是函数名的作用。

闭包不用声明返回值,但它却可以有返回值。并且使用最后一条语句的执行结果作为返回值。闭包的返回值可以赋值给变量。

闭包有时候有些地方又称之为 内联函数。这种特性使得闭包可以访问外层函数里的变量。

对于那些只使用一次的函数,使用闭包是最佳的代替方案。

1. 定义闭包的语法

在介绍如何定义闭包前,我们先来看看 如何定义一个普通的函数

一个普通的函数的定义语法格式如下

fn function_name(parameters) -> return_type {
   // 函数的具体逻辑
}

从上面的描述中我们知道,闭包是一个没有函数名的内联函数。它的定义语法如下

|parameter| {
   // 闭包的具体逻辑
}

从语法格式上来看,闭包就是普通函数去掉 fn 关键字,去掉函数名,去掉返回值声明,并把一对小括号改成一对 竖线 ||。

闭包的参数是可选的,如果一个闭包没有参数,那么它的定义语法格式如下

||{
   // 闭包的具体逻辑  
}

闭包虽然没有名称,但我们可以将闭包赋值给一个变量,然后就可以通过调用这个变量来完成闭包的调用。

let closure_function = |parameter| {
   // 闭包的具体逻辑
}

因为调用闭包的语法实现了 Fn 特质,因此我们可以像调用普通函数那样,使用小括号 () 来调用闭包

closure_function(parameter);    //invoking

2. 闭包范例:普通的闭包

下面的代码我们定义了一个闭包用于判断传递的参数是否偶数,并把闭包赋值给变量 is_even

然后我们通过调用 is_even() 来完成闭包的调用。

fn main(){
   let is_even = |x| {
      x%2==0
   };
   let no = 13;
   println!("{} is even ? {}",no,is_even(no));
}

编译运行以上 Rust 代码,输出结果如下

13 is even ? false

3. 闭包范例:闭包使用外部函数可以访问的变量

闭包还可以访问它所在的外部函数可以访问的所有变量。

fn main(){
   let val = 10; 
   // 访问外层作用域变量 val
   let closure2 = |x| {
      x + val // 内联函数访问外层作用域变量
   };
   println!("{}",closure2(2));
}

编译运行以上 Rust 代码,输出结果如下

12

下一章:Rust 智能指针

Rust 作为一种系统级语言,为了既能提高运行效率,又能保证数据安全,所以提供了有限的指针功能。Rust 语言为了保证安全性,尽可能抛弃指针,也就是默认会把所有的数据都存储在栈上。如果要把数据存储堆上,就要在上开辟内存,这时候就要使用到 指针。访问 Box 指针存储的数据。