IB-Rust-闭包
闭包介绍
什么是闭包?
- 闭包是一个可以捕获所在环境中的变量的匿名函数
- 闭包通过
||符号定义,可以像普通函数一样调用,但与函数不同,闭包可以访问外部作用域的变量
闭包的特点
- 可以捕获周围作用域的变量
- 支持作为参数传递给其他函数
- 可以返回闭包作为函数的返回值
- 闭包通常通过类型推断来确定参数和返回值的类型
闭包定义
1 | let add_one = |x: i32| -> i32 { x + 1 }; |
省略类型的闭包
Rust 可以推断闭包的参数和返回值类型,因此在很多情况下可以省略类型声明
1 | let add_one = |x| x + 1; |
闭包的使用
作为函数参数
闭包可以作为函数的参数传递,从而实现更灵活的代码结构
1 | fn apply_to_3<F>(f: F) -> i32 |
捕获环境变量
闭包可以捕获并使用其定义所在环境中的变量
1 | let x = 4; |
闭包的三种捕获方式
- 按值捕获(move 语义):将环境变量的所有权移入闭包
- 按引用捕获:通过引用捕获环境变量
- 按可变引用捕获:通过可变引用捕获环境变量
1 | let mut num = 5; |
闭包的原理
自动实现的函数类型
Fn、FnMut和FnOnce是 Rust 提供的三种函数闭包类型,分别表示按引用捕获、按可变引用捕获和按值捕获
闭包的类型推断
- Rust 能够根据闭包的使用上下文推断出闭包的具体类型
Fn、FnMut和FnOnce是闭包在不同情况下自动实现的 trait
生命周期与闭包
- 闭包可以捕获引用,但需要保证引用的生命周期超过闭包的生命周期
1 | let s = String::from("hello"); |
创建闭包时,通过闭包对环境值的使用,Rust 能推断出具体使用哪个 trait:
- 所有的闭包都实现了
FnOnce - 没有 move 捕获变量的实现了
FnMut - 无需可变访问捕获变量的闭包实现了
Fn
move 关键字
在参数列表前使用 move 关键字,可以强制闭包取得它所使用用的环境值的所有权。一般用于:将闭包传递给新线程以移动数据使其归新线程所有
1 | let x = vec![1, 2, 3]; |
课后习题
假设你正在开发一个博客系统,其中每个用户可以查看不同的文章页面。页面的渲染是一个计算密集型的过程,可能涉及数据库查询、模板渲染等操作。因此,为了优化性能,你决定在服务器端实现一个缓存系统。
要求:
- 实现 PageCache 结构体:
- 该结构体应缓存根据 用户ID 和 文章ID 渲染的页面。
- 你需要为该结构体实现一个 get_page 方法,该方法接受 用户ID 和 文章ID,并返回渲染后的页面内容。
- 如果相同的 用户ID 和 文章ID 已经渲染过,则 get_page 应直接返回缓存的页面,而不是重新渲染。
通用性:
- PageCache 应支持任意类型的 用户ID(例如,u32 或 String)和 文章ID。
- 缓存的内容应为渲染后的 HTML页面(String 类型)。
示例:
1 | fn main() { |
1 | use std::collections::HashMap; |
- Title: IB-Rust-闭包
- Author: Gabrielle
- Created at : 2025-06-11 23:46:23
- Updated at : 2025-06-14 15:19:50
- Link: https://zoella-w.github.io/2025/06/11/80-IB-Rust-闭包/
- License: This work is licensed under CC BY-NC-SA 4.0.