rust学习笔记21-闭包

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

1. 基本语法

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

// 无参数的闭包
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):消费环境变量(只能调用一次)。

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 等。

示例:使用闭包过滤偶数

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: 表示闭包只能调用一次,通常是因为它需要获取环境变量的所有权。

// 接受 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.线程中传递闭包

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 保证行为正确性。
通过合理利用闭包,你可以写出更加直观、高效的代码,尤其是在处理数据转换、异步编程等场景下。

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

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

相关文章

linux实现rsync+sersync实时数据备份

1.概述 rsync(Remote Sync) 是一个Unix/linux系统下的文件同步和传输工具 2.端口和运行模式 tcp/873 采用C/S模式&#xff08;客户端/服务器模式&#xff09; 3.特点 可以镜像保存整个目录和文件第一次全量备份(备份全部的文件),之后是增量备份(只备份变化的文件) 4. 数…

【第30节】MFC编程:ListCtrl控件和TreeCtrl控件

目录 引言 一、高级控件ListCtrl 二、高级控件TreeCtrl 三、Shell控件 四、CImageList 五、综合代码示例 引言 在MFC编程里&#xff0c;高级控件能大幅提升应用程序的交互性与功能性。接下来&#xff0c;咱们会详细讲讲ListCtrl和TreeCtrl这两个高级控件。不仅会介绍它们…

为什么 ThreadLocalMap 的 key 是弱引用 value是强引用

问题一&#xff1a;为什么 ThreadLocalMap 的 key 是弱引用&#xff1f; 【假设 Entry 的 key 是对 ThreadLocal 对象的强引用】&#xff1a;这个 Entry 又持有 ThreadLocal 对象和 value 对象的强引用。如果在其他地方都没有对这个 ThreadLocla 对象的引用了、然后在使用 Thr…

DeepSeek本地部署(linux)

一、下载并安装Ollama 1.下载Ollama Ollama官网:Ollama 点击"Download",会跳转至下载页面。 1.1在线下载安装 可复制此命令到Linux服务器进行在线下载,如下载速度过慢,可选择离线下载安装。 curl -fsSL https://ollama.com/install.sh | sh1.2离线下载安装 …

基于Halcon仿VM流程列表的执行效果

Halcon本身应用需要一定的门槛&#xff0c;但是也可以封装成类似VM简单易操作的样子 上期文章分享的是连线功能&#xff0c;本期分享数据传参 1&#xff0c;定义通用属性和方法 public class BaseModel {public HObject HInput { get; set; }//图像输入public HObject HOutpu…

打车APP订单系统逻辑梳理与实现

一、逻辑分析 打车 APP 订单系统是整个打车业务的核心&#xff0c;负责处理从乘客下单到行程结束的一系列流程&#xff0c;涉及乘客、司机和平台三方的交互。 乘客端 下单&#xff1a;乘客打开 APP&#xff0c;输入上车地点、目的地&#xff0c;选择车型等信息后提交订单。此时…

杂草YOLO系列数据集4000张

一份开源数据集——杂草YOLO数据集&#xff0c;该数据集适用于农业智能化、植物识别等计算机视觉应用场景。 数据集详情 ​训练集&#xff1a;3,664张高清标注图像​测试集&#xff1a;180张多样性场景样本​验证集&#xff1a;359张严格筛选数据 下载链接 杂草YOLO数据集分…

算法 | 河马优化算法原理,公式,应用,算法改进及研究综述,matlab代码

以下是关于河马优化算法(Hippopotamus Optimization Algorithm, HO)的完整综述,包含原理、公式、应用场景、改进方向及可直接运行的 Matlab 完整代码。一、算法原理 河马优化算法(HO)由Amiri等人于2024年提出,是受河马群体行为启发的元启发式算法,其核心基于以下三阶段行…

知识就是力量——HELLO GAME WORD!

你好&#xff01;游戏世界&#xff01; 简介环境配置前期准备好文章介绍创建头像小功能组件安装本地中文字库HSV颜色空间音频生成空白的音频 游戏UI开发加载动画注册登录界面UI界面第一版第二版 第一个游戏&#xff08;贪吃蛇&#xff09;第二个游戏&#xff08;俄罗斯方块&…

Android Activity 的 launchMode 与 Task Stack 管理

Android 中的 android:launchMode 决定了 Activity 在启动时如何在任务栏中管理它的存在方式。下面我们来结合 Task Stack 管理详细解释。 1. android:launchMode 的四种模式 1.1 standard (标准模式, 默认) 启动方式&#xff1a;每次启动都会创建一个新实例并压入栏任务堆中…

2025选择手机之我见

自从开店之后&#xff0c;没当有手机召开发布会&#xff0c;我就得去大概看看&#xff0c;了解一下屏幕&#xff0c;充电之类的东西。毕竟跟我的生意息息相关&#xff0c;而且还得研究要不要上新&#xff0c;从我目前卖货的情况来看&#xff0c;折叠屏不是大众的选择&#xff0…

【区块链安全 | 第九篇】基于Heimdall设计的智能合约反编译项目

文章目录 背景目的安装1、安装 Rust2、克隆 heimdall-dec3、编译 heimdall-dec4、运行 heimdall-dec 使用说明1、访问 Web 界面2、输入合约信息3、查看反编译结果 实战演示1、解析普通合约2、解析代理合约 背景 在区块链安全研究中&#xff0c;智能合约的审计和分析至关重要。…

利用 PCI-Express 交换机实现面向未来的推理服务器

在数据中心系统的历史上&#xff0c;没有比被 Nvidia 选为其 AI 系统的组件供应商更高的赞誉了。 这就是为什么新兴的互连芯片制造商 Astera Labs 感到十分高兴&#xff0c;因为该公司正在 PCI-Express 交换机、PCI-Express 重定时器和 CXL 内存控制器方面与 Broadcom 和 Marv…

智能交通预警杆:守护道路安全的科技先锋

在城市化进程加速以及机动车保有量持续增长的背景下&#xff0c;道路交通安全与拥堵问题渐趋严峻。智能交通预警杆应时而生&#xff0c;其集成多种高科技功能&#xff0c;正逐步成为现代城市交通管理中至关重要的智能装备&#xff0c;对于提升交通效率、保障出行安全发挥着关键…

flink 基站与服务器长连接,每次连接和断开都会上报数据,统计过去一小时每个基站断开次数和时长

模拟生成数据 CREATE TABLE ods_station_log (base_station_id int, -- 基站IDevent_type int, -- 事件类型: connect/disconnectevent_time TIMESTAMP_LTZ(3), -- 事件时间WATERMARK FOR event_time AS event_time - INTERVAL 5 SECOND -- 允许5秒乱序 ) WITH …

自定义一些C语言的字符串函数

一、代码如下 (一)十六进制字符串转十进制整数 #include<stdio.h> // 把一个十六进制字符转成十进制整数 int hexToInt(char hexs[]){ int index; int k 0; for(k 0; ; k) { if(hexs[k] \0) { index k; break; …

核函数(机器学习深度学习)

一、核函数的基本概念 核函数&#xff08;Kernel Function&#xff09; 是机器学习中处理非线性问题的核心工具&#xff0c;通过隐式映射将数据从原始空间转换到高维特征空间&#xff0c;从而在高维空间中实现线性可分或线性建模。其数学本质是计算两个样本在高维空间中的内积…

微服务架构中的精妙设计:服务注册/服务发现-Eureka

一.使用注册中心背景 1.1服务远程调用问题 服务之间远程调⽤时, 我们的URL是写死的 String url "http://127.0.0.1:9090/product/" orderInfo.getProductId(); 缺点&#xff1a; 当更换机器, 或者新增机器时, 这个URL就需要跟着变更, 就需要去通知所有的相关服…

极速版:栈的内存/局部变量表/堆的内存细分

1. 栈的存储 每个线程都有自己的栈&#xff0c;栈中数据以栈帧&#xff08;Stack Frame&#xff09;为基本单位 线程上正在执行的每个方法都各自对应一个栈桢&#xff08;Stack Frame&#xff09; 栈桢是一个内存区块&#xff0c;是一个数据集&#xff0c;维系着方法执行过程…

【操作系统】内存泄漏 vs 内存碎片

【操作系统】内存泄漏 vs 内存碎片 内存泄漏&#xff08;Memory Leak&#xff09; vs 内存碎片&#xff08;Memory Fragmentation&#xff09;1. 内存泄漏&#xff08;Memory Leak&#xff09;2. 内存碎片&#xff08;Memory Fragmentation&#xff09;3. 内存泄漏 vs 内存碎片…