当前位置:嗨网首页>书籍在线阅读

09-闭包

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

1.3.4 闭包

Rust也支持闭包。闭包与函数类似,但具有声明它们的环境或作用域的更多信息。虽然函数具有与之关联的名称,闭包的定义没有,但可以将它们分配给变量。Rust类型推断的另一个优点是,在大多数情况下,你可以为没有类型的闭包指定参数。这是一个最简单的闭包“let my_closure = || ();”。我们刚刚定义了一个什么都不做的无参数闭包。然后我们可以通过my_closure()来调用它,这和函数类似。两个竖条“||”用于存放闭包的参数(如果有的话),例如|a,b|。当Rust无法找出正确的类型时,有时需要指定参数类型(|a:u32|)。和函数类似,闭包也可以存储在变量中,稍后调用或传递给其他函数。但是,闭包的主体可以是单一表达式,也可以是由花括号标识的多个表达式组成。更复杂的闭包示例如下所示:

// closures.rs
fn main() {
    let doubler = |x| x * 2;
    let value = 5;
    let twice = doubler(value);
    println!("{} doubled is {}", value, twice);
    let big_closure = |b, c| {
        let z = b + c;
        z * twice
    };
    let some_number = big_closure(1, 2);
    println!("Result from closure: {}", some_number);
}

在上述代码中,我们定义了两个闭包:doubler和big_closure。doubler将给定的值加倍。在这种情况下,它从父作用域或上下文环境传递value,即main函数。同样,在big_closure中,我们从其环境中使用变量twice。这个闭包在花括号内有多行表达式,需要以分号结尾,以便我们将它分配给变量big_closure。之后,我们调用big_closure,传入1、2作为参数,并输出some_number。

闭包主要用作高阶函数的参数。高阶函数是一个以另一个函数或闭包作为参数的函数。例如,标准库中的thread::spawn函数接收一个闭包作为参数,你可以在其中编写要在另一个线程中运行的代码。闭包提供简便、抽象的另一个场景是,当你有一个对Vec等集合进行操作的函数时,希望根据某些条件过滤元素。Rust的迭代器特征(iterator trait)有一个名为filter的方法,可以接收一个闭包作为参数。此闭包由用户定义,并返回true或false,具体取决于用户希望过滤集合中元素的方式。我们将在第7章深入了解闭包。