Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

English Original

12. 闭包 (Closures) 🟢

Rust 的 闭包 是可以保存在变量中或作为参数传递给其他函数的 匿名函数。你可以在一个地方创建闭包,然后在不同的上下文中调用闭包进行求值。

1. 基础语法

闭包使用竖线 || 而不是圆括号 () 来放置参数。

fn main() {
    let add_one = |x: i32| x + 1;
    let result = add_one(5);
    println!("结果是 {result}");
}

2. 捕获环境

与函数不同,闭包可以从定义它们的作用域中捕获值。

fn main() {
    let x = 4;
    let equal_to_x = |z| z == x; // 捕获了 `x`

    let y = 4;
    assert!(equal_to_x(y));
}

3. 闭包 Trait:FnFnMutFnOnce

闭包以三种方式从其环境中捕获值,这三种方式对应于函数获取参数的三种方式:

  • FnOnce:消耗其从闭包外层作用域捕获的变量(只能被调用一次)。
  • FnMut:以可变方式从其环境中借用值(可以修改环境)。
  • Fn:以不可变方式从其环境中借用值。

4. 使用 move 移动所有权

如果你想强制闭包获取其在环境中使用的值的所有权,可以在参数列表之前使用 move 关键字。

use std::thread;

fn main() {
    let x = vec![1, 2, 3];

    let handle = thread::spawn(move || {
        println!("这是一个向量:{:?}", x);
    });

    handle.join().unwrap();
}

对 C/C++ 开发者的总结

  • In C++:你使用 Lambdas ([=](int x) { ... })。你必须手动指定如何捕获变量(按值 [=]、按引用 [&] 等)。
  • In Rust:闭包会根据环境变量的使用方式自动推断应使用哪种捕获 Trait。move 关键字用于将所有权移动到闭包中,类似于 C++ 中的 [x = std::move(x)]