rust学习笔记21-闭包

在 Rust 中,闭包(Closures) 是一种可以捕获其环境中的变量的匿名函数。它们非常灵活,既可以作为普通函数使用,也可以捕获和操作定义它们的作用域中的变量。闭包是 Rust 中处理短小逻辑代码块的强大工具,特别是在需要将逻辑作为参数传递给其他函数时。

1. 基本语法

闭包的语法简洁,用 |参数| { 代码块 } 表示:

rust 复制代码
// 无参数的闭包
let greet = || println!("Hello, Rust!");
greet();

// 带参数的闭包
let add = |a: i32, b: i32| -> i32 { a + b };
println!("Sum: {}", add(3, 5));

// 类型可省略(编译器自动推断)
let multiply = |x, y| x * y; 
println!("Product: {}", multiply(4, 5));

2. 捕获环境变量

闭包可以捕获其定义时的作用域变量,捕获方式分为三种(对应三个 trait):

不可变借用(Fn):只读取环境变量。

可变借用(FnMut):可修改环境变量。

所有权转移(FnOnce):消费环境变量(只能调用一次)。

rust 复制代码
fn main() {
    // 不可变借用
    let name = "rust";
    let print_name = || println!("Name: {}", name); // 捕获 name 的不可变引用
    print_name(); // 可多次调用

    // 可变借用
    let mut count = 0;
    let mut increment = || { 
    count += 1; // 捕获可变引用
    println!("Count: {}", count);
    };
    increment(); // 可多次调用,但闭包本身需声明为 mut
    // 所有权移动
    let x = vec![1, 2, 3];
    let closure = move || println!("x: {:?}", x); // 获取所有权
    closure();
    //println!("{:?}", x); // 错误: x 已被移动到闭包中

}

3. 闭包作为函数参数

闭包经常被用作函数参数,特别是对于高阶函数(Higher-order Functions),例如 map, filter, fold 等。

示例:使用闭包过滤偶数

rust 复制代码
fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6];
    let even_numbers: Vec<i32> = numbers.into_iter().filter(|&x| x % 2 == 0).collect();
    println!("Even numbers: {:?}", even_numbers); // 输出: Even numbers: [2, 4, 6]
}

4. 闭包与 Trait

Rortex 内部使用了三个 Trait 来表示闭包的行为:

Fn: 表示闭包可以通过引用调用。

FnMut: 表示闭包可以通过可变引用调用。

FnOnce: 表示闭包只能调用一次,通常是因为它需要获取环境变量的所有权。

rust 复制代码
// 接受 Fn 闭包(不可变借用)
fn run_closure<F: Fn()>(f: F) {
    f();
}

// 接受 FnMut 闭包(可变借用)
fn run_mut_closure<F: FnMut()>(mut f: F) {
    f();
}

// 接受 FnOnce 闭包(所有权转移)
fn run_once_closure<F: FnOnce()>(f: F) {
    f();
}

5. 性能特点

零成本抽象:闭包通常被编译为普通函数,无运行时开销。

内联优化:编译器可能将闭包内联,提升性能。

内存分配:默认在栈上分配,使用 Box 时才会堆分配。

6.线程中传递闭包

rust 复制代码
fn main() {
    use std::thread;

    let value = 42;
    let handle = thread::spawn(move || { // 强制转移所有权到线程
        println!("Value in thread: {}", value);
    });
    handle.join().unwrap();
}

总结

Rust 闭包通过以下机制实现强大功能:

灵活捕获环境:支持不可变/可变借用和所有权转移。

零成本抽象:编译时生成高效代码。

类型安全:通过 Fn、FnMut、FnOnce trait 保证行为正确性。

通过合理利用闭包,你可以写出更加直观、高效的代码,尤其是在处理数据转换、异步编程等场景下。

相关推荐
克里斯蒂亚诺更新7 小时前
ruoyi角色权限的对应关系
笔记
a1117769 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
我的xiaodoujiao9 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest
doiito10 小时前
【AI 应用】从“外国人味”到地道中文:kokoroi-rs v0.1.2 架构升级深度解析
ai·rust·系统设计
破碎的南瓜11 小时前
sqli--sql注入过关笔记(1,2,3,4,5,9)
数据库·笔记·sql
你想知道什么?11 小时前
线性回归-学习笔记
笔记·学习·线性回归
鱼毓屿御11 小时前
从「只会聊」到「边想边做」的跃迁
前端·学习·react.js
谙弆悕博士11 小时前
系统集成项目管理工程师教程(第3版)笔记——第17章:法律法规和标准规范
笔记·职场和发展·学习方法·业界资讯·软考·法律·法规
AOwhisky13 小时前
Python 学习笔记(第十五期)——运维自动化(下·后篇):堡垒机实战——paramiko高阶篇
运维·python·学习·云原生·自动化·运维开发
谙弆悕博士13 小时前
系统集成项目管理工程师教程(第3版)笔记——第4章:信息系统架构
笔记·系统架构·项目管理·创业创新·学习方法·业界资讯·物理