Rust闭包详解

文章目录

闭包

Rust中的闭包是一种匿名函数,可以捕获并存储环境中的变量,有点类似于Lambda表达式

闭包允许在其定义的作用域之外访问变量,并且可以在需要时将其移动或者借用给闭包

闭包在Rust中被广泛应用于函数式编程、并发编程和事件驱动编程等领域

比较适合用于短小的自定义逻辑的场景

rust 复制代码
let name = |参数列表| 表达式或语句块;
let add = |x: i32| x + 1;
let cal = |x, y, z| x * y + z;
let res = cal(1, 2, 3);

捕获外部变量

闭包可以捕获环境中的变量

rust 复制代码
let x = 5;
let add = |num| num + x;
println!("{}", add(1)); // 输出 6

捕获变量有三种方法

  • 传引用捕获(默认的,类似于 &T)
  • 传值捕获(类似 T)
  • 借用捕获(类似 &mut T)
rust 复制代码
fn main(){
  let mut num = 114;
  
  let print_num = || println!("num = {}", num);
  print_num(); // 直接输出内容
  
  let take_num = move || println!("num taken = {}", num);
  take_num(); // 直接输出内容
  // println!("{}", num); // 取消注释会报错,因为num的所有权被转移了
  
  let mut change_num = || num += 1;
  change_num();
  println!("num = {}", num);
}
  • 默认是按照引用捕获外部变量的
  • 使用move关键字可以强制按值捕获,但是所有权会转移到闭包内部,这里关于所有权的问题,我们会在后面讲解
  • 如果闭包需要修改外部变量,需要显示声明为mut闭包

移动和借用

闭包可以通过move关键字获取外部变量的所有权,或者通过借用的方式获取外部变量的引用

借用:默认情况下,闭包会借用他捕获的环境中的变量,闭包可以使用这些变量,但是不能修改他们的所有权,此时闭包内部和外部的作用域都可以使用这个变量

获得所有权:在闭包之前添加move关键字,闭包会获取他捕获的变量的所有权,此时,变量的所有权会转移到内部,外部作用域无法使用这些变量

闭包的特性

  1. 闭包可以作为参数传递给函数,例如迭代器的map,filter方法都需要用到闭包
  2. 闭包还可以作为返回值,由于闭包是匿名的,我们需要使用impl Trait 或者

例如

使用 impl Fn 返回闭包

rust 复制代码
fn apply_to_value<F>(val: i32, f: F) -> i32
where
    F: Fn(i32) -> i32,
{
    f(val)
}

fn main() {
    let double = |x| x * 2;
    let result = apply_to_value(5, double);
    println!("Result: {}", result); // 输出: Result: 10
}

使用 Box<dyn Fn>返回闭包

rust 复制代码
fn make_adder(x: i32) -> Box<dyn Fn(i32) -> i32> {
    Box::new(move |y| x + y)
}

fn main() {
    let add_ten = make_adder(10);
    println!("10 + 2 = {}", add_ten(2)); // 输出: 10 + 2 = 12
}

闭包和性能

Rust 的闭包是轻量级的,并且 Rust 的编译器会进行优化,使得闭包的调用接近于直接调用函数。

闭包和生命周期

闭包的生命周期与它们所捕获的变量的生命周期相关。Rust 的生命周期系统确保闭包不会比它们捕获的任何变量活得更长。

相关推荐
Chester_19996 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
EXI-小洲7 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员8 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导8 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan8 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
m0_695251498 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
q平面人8 小时前
【总工笔记】mindoc平板、桌面端笔记软件,发布到mindoc服务端
rust·tauri·华为平板·mindoc·总工笔记
大衛說9 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
MC皮蛋侠客10 小时前
Tauri 2.x 系列(九):安全模型——Capabilities、Permissions、Scope 与 CSP
rust·tauri
可乐鸡翅yeah_10 小时前
hls.js 内存泄漏实战排查,直播 M3U8 长时间播放异常定位方案
开发语言·javascript·python·django·ecmascript·m3u8·m3u8在线