Rust闭包(能够捕获周围作用域变量的匿名函数,广泛应用于迭代、过滤和映射)闭包变量三种捕获方式:通过引用(不可变引用)、通过可变引用和通过值(取得所有权)

文章目录

      • Rust 闭包详解
        • 闭包的定义与语法
          • 基本语法
        • 闭包的特性
          • - 环境捕获(三种捕获方式:通过引用、通过可变引用和通过值(取得所有权))
            • 示例代码
          • - 内存安全与生命周期
            • 示例代码1
          • 示例代码2:闭包所有权转移
          • 示例代码3:传递可变引用
        • Rust 闭包的实际应用
          • - 迭代器操作
            • 示例代码
        • 总结
      • 补充:闭包变量三种捕获方式:通过引用(不可变引用)、通过可变引用和通过值(取得所有权)代码对比示例
        • 1. 通过引用捕获(不可变引用)
        • 2. 通过可变引用捕获
        • 3. 通过值捕获(取得所有权)

Rust 闭包详解

Rust 语言的闭包是一种能够捕获周围作用域变量的匿名函数。闭包在 Rust 中具有强大的表达力和灵活性,广泛应用于迭代、过滤和映射等功能。本文将深入探讨 Rust 闭包的定义、语法、特性以及实际应用示例。

闭包的定义与语法

闭包是 Rust 中一个可以捕获其环境并可以访问其作用域中变量的匿名函数。闭包通常是简短的,并且被定义在期望函数作为参数的地方。

基本语法

在 Rust 中,闭包的基本语法如下所示:

let closure_name = |parameter_list| -> return_type {// 闭包体
};

闭包的定义开始于一个竖线 |,后面跟着参数列表,参数列表的结尾也是一个竖线 |。可选的返回类型可以使用 -> 符号指定,闭包体由花括号 {} 包裹。

闭包的特性
- 环境捕获(三种捕获方式:通过引用、通过可变引用和通过值(取得所有权))

闭包可以通过三种方式捕获其环境中的变量:通过引用、通过可变引用和通过值(取得所有权)。Rust 的编译器会根据闭包体内所使用的变量的方式自动推断如何捕获这些变量。

示例代码
// 测试代码
#![allow(dead_code)] // 忽略全局dead code,放在模块开头!// #[derive(Debug)]fn main() {let x = 4;let equal_to_x = |z| z == x;let y = 4;assert!(equal_to_x(y));println!("y is equal to x.");
}

在这里插入图片描述

在上述示例中,闭包 equal_to_x 通过引用捕获变量 x,因为闭包内部只是将 x 与传入的参数 z 进行比较,不需要修改 x

- 内存安全与生命周期

Rust 的所有权和借用规则同样适用于闭包。这意味着闭包内的捕获变量必须保证在闭包被调用时是有效的。Rust 编译器会检查这一点,确保闭包的使用是安全的。

示例代码1
// 测试代码
#![allow(dead_code)] // 忽略全局dead code,放在模块开头!// #[derive(Debug)]fn main() {let mut num = 5;{let mut add_num = |x: i32| num += x;add_num(5);}assert_eq!(num, 10);println!("num is now 10.");
}

在这里插入图片描述

这里的 add_num 闭包通过可变引用捕获外部变量 num,并在闭包体内修改 num 的值。

示例代码2:闭包所有权转移
// 测试代码
#![allow(dead_code)] // 忽略全局dead code,放在模块开头!// #[derive(Debug)]fn main() {let s = String::from("Hello");let push_string = |mut s_: String| s_.push_str(", world");push_string(s);// assert_eq!(s, String::from("Hello, world")); // 报错// println!("s is now \"Hello, world\".");
}
示例代码3:传递可变引用
// 测试代码
#![allow(dead_code)] // 忽略全局dead code,放在模块开头!// #[derive(Debug)]fn main() {let mut s = String::from("Hello");let push_string = |s_: &mut String| s_.push_str(", world");push_string(&mut s);assert_eq!(s, String::from("Hello, world"));println!("s is now \"Hello, world\".");
}

在这里插入图片描述

Rust 闭包的实际应用
- 迭代器操作

Rust 中的迭代器广泛使用闭包,尤其是在 mapfilterfold 等方法中。

示例代码
// 测试代码
#![allow(dead_code)] // 忽略全局dead code,放在模块开头!// #[derive(Debug)]fn main() {let numbers = vec![1, 2, 3, 4, 5];let squared_numbers: Vec<i32> = numbers.iter().map(|&x| x * x).collect();println!("Squared numbers: {:?}", squared_numbers); // 输出: [1, 4, 9, 16, 25]let even_numbers: Vec<i32> = numbers.into_iter().filter(|x| x % 2 == 0).collect();println!("Even numbers: {:?}", even_numbers); // 输出: [2, 4]
}

在这里插入图片描述

这个示例展示了如何使用闭包在迭代器上执行映射和过滤操作,map 用于计算平方,filter 用于选择偶数。

总结

Rust 的闭包提供了一个强大且灵活的工具,能够在许多不同的情境下灵活处理数据。通过闭包,Rust 程序员可以编写出既安全又高效的代码。

补充:闭包变量三种捕获方式:通过引用(不可变引用)、通过可变引用和通过值(取得所有权)代码对比示例

当然可以。以下是三个独立的代码块,每个代码块展示了 Rust 闭包中一种特定的变量捕获方式:通过引用、通过可变引用、和通过值(取得所有权)。每个示例都会通过闭包的参数来展示具体的捕获操作。

1. 通过引用捕获(不可变引用)

这个示例演示了闭包如何通过不可变引用捕获外部环境中的变量。

// 测试代码
#![allow(dead_code)] // 忽略全局dead code,放在模块开头!// #[derive(Debug)]fn main() {let color = String::from("blue");// 通过不可变引用捕获 colorlet print_color = |color_ref: &String| println!("Color: {}", color_ref);print_color(&color);
}

在这里插入图片描述

这里,print_color 是一个接收一个 &String 类型参数的闭包,它通过不可变引用来访问外部定义的 color 变量。

2. 通过可变引用捕获

这个示例展示了闭包如何通过可变引用捕获并修改外部环境中的变量。

// 测试代码
#![allow(dead_code)] // 忽略全局dead code,放在模块开头!// #[derive(Debug)]fn main() {let mut count = 0;// 通过可变引用捕获 countlet increment_count = |count_ref: &mut i32| {*count_ref += 1;println!("Count: {}", *count_ref);// println!("Count: {}", count_ref); // 都可以,自动判断的};increment_count(&mut count);increment_count(&mut count);
}

在这里插入图片描述

在这个示例中,increment_count 是一个接收 &mut i32 类型参数的闭包,它通过可变引用来修改传入的 count 变量。

3. 通过值捕获(取得所有权)

这个示例演示了闭包如何通过值捕获(取得所有权)外部环境中的变量。

// 测试代码
#![allow(dead_code)] // 忽略全局dead code,放在模块开头!// #[derive(Debug)]fn main() {let color = String::from("blue");// 通过值捕获 colorlet consume_color = |color_val: String| println!("Moved Color: {}", color_val);consume_color(color);// 注意:在这里调用 consume_color 后,color 不再有效// 下面的代码如果取消注释,将会引起编译错误,因为 color 的所有权已经移至闭包中// println!("Try to access color: {}", color);
}

在这里插入图片描述

在这个示例中,consume_color 是一个接收 String 类型参数的闭包,它通过值捕获来获取 color 的所有权。一旦闭包被调用,原始的 color 变量就不再可用了。


这些代码块展示了如何明确通过闭包参数直接传递外部变量,并通过不同的捕获机制来处理这些变量。这种方式需要闭包调用者明确知道闭包的捕获机制和参数类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/466837.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【国内中间件厂商排名及四大中间件对比分析】

国内中间件厂商排名 随着新兴技术的涌入&#xff0c;一批国产中间件厂商破土而出&#xff0c;并在短时间内迅速发展&#xff0c;我国中间件市场迎来洗牌&#xff0c;根据市占率&#xff0c;当前我国中间件厂商排名依次为&#xff1a;东方通、宝兰德、中创股份、金蝶天燕、普元…

Java 源码中的 Unicode 逃逸问题,别被注释给骗了

背景 看了一段项目源码&#xff0c;定义了一个 List 对象&#xff0c;往该列表对象 add 的代码前面有注释符号&#xff0c;但是程序运行时列表中却存在对象&#xff0c;为什么呢&#xff1f;仔细看了一下&#xff0c;注释符号和 add 代码之间有一个特殊符号 \u000d&#xff0c…

基于IM场景下的Wasm初探:提升Web应用性能|得物技术

一、何为Wasm &#xff1f; Wasm&#xff0c;全称 WebAssembly&#xff0c;官网描述是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm被设计为一个可移植的目标&#xff0c;用于编译C/C/Rust等高级语言&#xff0c;支持在Web上部署客户端和服务器应用程序。 Wasm 的开发者参…

基于百度飞桨paddle的paddlepaddle2.4.2等系列项目的运行

PPASR 必看&#xff01;&#xff01;&#xff01; PaddleSpeech develop --> PaddlePaddle 2.5.0/2.5.1 PaddleSpeech < 1.4.1 --> PaddlePaddle < 2.4.2 1.创建虚拟环境 conda create --name test python3.10 2.激活环境&#xff0c;安装ppasr的paddlepaddl…

2024MoonBit全球编程创新挑战赛参赛作品“飞翔的小鸟”技术开发指南

本文转载自 CSDN&#xff1a;https://blog.csdn.net/m0_61243965/article/details/143510089作者&#xff1a;言程序plus 实战开发基于moonbit和wasm4的飞翔的小鸟游戏 游戏中&#xff0c;玩家需要通过上下左右按键控制Bird&#xff0c;在不断移动的障碍pipe之间穿梭&#xf…

浅谈Agent

目录 什么是大模型 Agent &#xff1f; 大模型Agent 有哪些部分组成? 规划&#xff08;Planning&#xff09; Planning类型 不依赖反馈的计划 基于反馈的计划 拆解子目标和任务分解方法 COT TOT GOT LLMP 反思和完善 ReAct(融合推理与执行的能力) Reflexion(动态…

文本转SQL(Text-to-SQL),场景介绍与 Spring AI 实现

在众多的 AI 大模型的应用场景中&#xff0c;Text-to-SQL&#xff0c;也就是文本转 SQL&#xff0c;是其中实用性很高的一个。Text-to-SQL 充分利用了大模型的优势&#xff0c;把用户提供的自然语言描述转换成 SQL 语句&#xff0c;还可以执行生成的 SQL 语句&#xff0c;再把查…

DICOM标准:深入详解DICOM医学影像中的传输语法

引言 DICOM&#xff08;数字成像和通信医学&#xff09;标准在医学影像数据交换中扮演着至关重要的角色。其中&#xff0c;*传输语法&#xff08;Transfer Syntax&#xff09;是DICOM标准中定义数据编码和传输方式的核心部分。理解传输语法对于确保不同设备和系统之间的互操作性…

如何提高谷歌收录速度?

相信很多做外贸推广的朋友都遇到过这种情况&#xff1a;网站上线了&#xff0c;但新页面迟迟不被谷歌收录。即使你的内容很优秀&#xff0c;设计也很精美&#xff0c;如果谷歌爬虫抓不到页面&#xff0c;一切努力就白费了。这时候&#xff0c;GSI谷歌快速收录服务就成了“救命稻…

Spring面向切面编程

目录 1.AOP概述及Spring AOP实现原理 AOP概述 AOP的应用场景 AOP的作用 Spring AOP概述 Spring AOP的实现原理 Spring AOP中Advice的分类 2. 通过xml配置实现AOP 实现步骤&#xff1a; 新增模块&#xff1a; 导入相关依赖&#xff1a; 新增实体类User 新增业务类UserS…

Notepad++ 更改字体大小和颜色

前言 在长时间编程或文本编辑过程中&#xff0c;合适的字体大小和颜色可以显著提高工作效率和减少眼睛疲劳。Notepad 提供了丰富的自定义选项&#xff0c;让你可以根据个人喜好调整编辑器的外观。 步骤详解 1. 更改字体大小 打开 Notepad 启动 Notepad 编辑器。 进入设置菜…

香港航空 阿里滑块 acw_sc__v3 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像私信联系我删…

Unet++改进3:添加NAMAttention注意力机制

本文内容:添加NAMAttention注意力机制 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 识别不太显著的特征是模型压缩的关键。然而,它在革命性的注意机制中尚未得到研究。在这项工作中,我们提出了一种新的基于归一化的注意力模块(NAM),它抑制了较不显著…

WPF+MVVM案例实战(二十二)- 制作一个侧边弹窗栏(CD类)

文章目录 1、案例效果1、侧边栏分类2、CD类侧边弹窗实现1、样式代码实现2、功能代码实现3 运行效果4、源代码获取1、案例效果 1、侧边栏分类 A类 :左侧弹出侧边栏B类 :右侧弹出侧边栏C类 :顶部弹出侧边栏D类 :底部弹出侧边栏2、CD类侧边弹窗实现 1、样式代码实现 在原有的…

汽车广告常见特效处理有哪些?

​汽车广告作为展示汽车性能和外观的重要媒介&#xff0c;常常需要借助特效来增强视觉效果&#xff0c;吸引观众的注意力。以下是一篇关于汽车广告中常见特效处理的文章。 在竞争激烈的汽车市场中&#xff0c;广告不仅是推广产品的工具&#xff0c;更是艺术和科技的结合。特效技…

【CUDA】线程配置

一、 线程层次结构 1.1 认识 GPU 可并行执行工作 Thread&#xff1a;所有线程执行相同的核函数&#xff0c;并行执行 Thread Block&#xff1a;执行在一个Streaming Multiprocessor (SM)&#xff0c;同一个Block中的线程可以协作 线程的集合称为块&#xff0c;块的数量很多…

爬虫-------字体反爬

目录 一、了解什么是字体加密 二. 定位字体位置 三. python处理字体 1. 工具库 2. 字体读取 3. 处理字体 案例1&#xff1a;起点 案例2&#xff1a;字符偏移&#xff1a; 5请求数据 - 发现偏移量 5.4 多套字体替换 套用模板 版本1 版本2 四.项目实战 1. 采集目…

transformer模型写诗词

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

【计算机网络】章节 知识点总结

一、计算机网络概述 1. 计算机网络向用户提供的两个最重要的功能&#xff1a;连通性、共享 2. 因特网发展的三个阶段&#xff1a; 第一阶段&#xff1a;从单个网络 ARPANET 向互联网发展的过程。1983 年 TCP/IP 协议成为 ARPANET 上的标准协议。第二阶段&#xff1a;建成三级…

【微服务】不同微服务之间用户信息的获取和传递方案

如何才能在每个微服务中都拿到用户信息&#xff1f;如何在微服务之间传递用户信息&#xff1f; 文章目录 概述利用微服务网关做登录校验网关转微服务获取用户信息openFeign传递微服务之间的用户信息 概述 要在每个微服务中获取用户信息&#xff0c;可以采用以下几种方法&#…