Skip to content

闭包基础

> 理解闭包的概念和价值,掌握闭包的基本语法,学会使用闭包简化代码。

为什么需要闭包?

闭包语法

概念名称: 闭包是匿名函数,可以捕获环境变量。

语法结构:
┌──────────────────────────────────────┐
│  let 闭包名 = |参数| { 表达式 };      │
│       ↑      ↑    ↑                   │
│       名字  参数列表 闭包体            │
│                                       │
│  let add = |x| x + 1;                │
│  let add = |x: i32| -> i32 { x + 1 };│
│                                       │
│  捕获环境变量:                        │
│  let n = 10;                          │
│  let add_n = |x| x + n;  // 捕获 n   │
│                                       │
│  捕获方式:|&x|, |&mut x|, move闭包   │
└──────────────────────────────────────┘

最简示例

rust
fn main() {
    let add = |x| x + 1;
    println!("{}", add(5));  // 6
}
▶ Run

代码复用问题

rust
// 问题:需要对不同数据执行相同操作

// 方案 1:为每种操作写函数
fn add_one(x: i32) -> i32 { x + 1 }
fn add_two(x: i32) -> i32 { x + 2 }
fn multiply_by_2(x: i32) -> i32 { x * 2 }

// 方案 2:使用闭包(简洁)
let add_one = |x| x + 1;
let add_two = |x| x + 2;
let multiply_by_2 = |x| x * 2;
▶ Run

回调函数需求

rust
// 问题:需要传递"行为"给函数

// 使用闭包作为回调
fn process_data(data: Vec<i32>, transform: fn(i32) -> i32) -> Vec<i32> {
    data.into_iter().map(transform).collect()
}

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

    // 传递不同的"行为"
    let doubled = process_data(data.clone(), |x| x * 2);
    let squared = process_data(data.clone(), |x| x * x);
    let negated = process_data(data, |x| -x);

    println!("doubled: {:?}", doubled);
    println!("squared: {:?}", squared);
    println!("negated: {:?}", negated);
}
▶ Run

闭包的核心优势

┌─────────────────────────────────────────────────────┐
│              闭包的优势                              │
├─────────────────────────────────────────────────────┤
│                                                     │
│  1. 简洁性                                           │
│     • 无需写完整的函数定义                          │
│     • 类型推断减少冗余                              │
│     • 内联定义,逻辑清晰                            │
│                                                     │
│  2. 捕获环境                                        │
│     • 可以访问定义位置的变量                        │
│     • 自动管理借用关系                              │
│     • 实现"闭包"语义                                │
│                                                     │
│  3. 函数式编程                                      │
│     • 作为参数传递(高阶函数)                     │
│     • 作为返回值                                    │
│     • 链式组合操作                                  │
│                                                     │
│  4. 延迟计算                                        │
│     • 定义时不执行,调用时才执行                   │
│     • 惰性迭代器的基础                              │
│     • 控制流抽象                                    │
│                                                     │
└─────────────────────────────────────────────────────┘



---

## 小结

- 闭包是匿名函数,可以捕获环境变量
- `|参数| 表达式` 是最简洁的闭包语法
- 闭包提供简洁性、环境捕获、函数式编程、延迟计算四大优势
- 作为回调函数传递,实现高阶函数模式
- 类型推断让闭包更简洁,但类型一旦确定就不能改变

## 练习题

详见:[练习题](../../exercises/18-closures)