Rust学习笔记_12——闭包

news2024/12/26 19:27:42

Rust学习笔记_09——模式匹配
Rust学习笔记_10——守卫
Rust学习笔记_11——函数


闭包

文章目录

    • 闭包
      • 1. 基本特性
      • 2. 语法
      • 3. 类型
      • 4. 变量捕获方式
        • 4.1 不可变捕获(Immutable Capture)
        • 4.2 可变捕获(Mutable Capture)
        • 4.3 移动捕获(Move Capture)
      • 5. 示例


在Rust编程语言中,闭包(closures)是一种匿名函数,它能够捕获并存储其所在作用域内的变量,以便在稍后的某个时间点调用。闭包在Rust中非常有用,尤其是在处理回调函数、迭代器的适配器以及并行计算等场景时。闭包提供了灵活且强大的函数式编程特性。

1. 基本特性

  1. 匿名性:闭包没有名称,这使得它们非常适合作为参数传递给其他函数。
  2. 捕获环境:闭包可以捕获其定义作用域内的变量,这些变量在闭包被调用时仍然可用。捕获可以是不可变的(默认),也可以是可变的。
  3. 类型推断:Rust的编译器能够推断闭包的类型,但在某些情况下,你可能需要显式地指定类型(例如,在泛型上下文中)。
  4. 简洁性:闭包提供了一种简洁的方式来定义小型函数,尤其是当这些函数只需要在局部作用域内使用时。

2. 语法

Rust中的闭包使用||符号来定义,其语法类似于函数定义,但不需要指定函数名。闭包的参数和返回类型通常可以通过类型推断来确定。

let closure = |param1, param2| {
    // 函数体
    param1 + param2
};

3. 类型

闭包在Rust中是匿名的,但它们仍然有类型。这些类型通常很复杂,因此Rust允许你通过类型别名或泛型参数来简化闭包的使用。在大多数情况下,你不需要显式地指定闭包的类型,因为Rust的编译器能够推断它。

4. 变量捕获方式

4.1 不可变捕获(Immutable Capture)

不可变捕获是闭包捕获变量的默认方式。当闭包以不可变方式捕获变量时,它只能读取该变量的值,而不能修改它。这种方式保证了闭包内部对变量的访问是安全的,因为闭包不会改变变量的状态。

fn main() {
    let x = 10;

    // 定义一个闭包,它以不可变方式捕获变量x
    let print_x = || {
        println!("x = {}", x);
    };

    print_x(); // 输出: x = 10

    // 注意:闭包内部不能修改x的值
    // 下面的代码会导致编译错误
    // let modify_x = || {
    //     x = 20; // 错误:不能给不可变捕获的变量赋值
    // };
}
4.2 可变捕获(Mutable Capture)

可变捕获允许闭包修改其捕获的变量的值。为了使用可变捕获,你需要在闭包的定义中使用mut关键字来标记捕获的变量。这样,闭包就可以读取和修改该变量的值了。

fn main() {
    let mut counter = 0;

    // 定义一个闭包,它以可变方式捕获变量counter
    let increment = || {
        counter += 1;
        println!("counter = {}", counter);
    };

    increment(); // 输出: counter = 1
    increment(); // 输出: counter = 2
}
4.3 移动捕获(Move Capture)

移动捕获发生在闭包需要获取其捕获变量的所有权时。当闭包以移动方式捕获变量时,原始变量将不再可用,因为闭包已经接管了该变量的所有权。移动捕获通常发生在闭包需要将其捕获的变量带到另一个作用域或线程中时。

fn main() {
    let vec = vec![1, 2, 3];

    // 定义一个闭包,它以移动方式捕获变量vec
    let print_vec = || {
        for &x in &vec {
            println!("{}", x);
        }
    };

    // 在移动捕获后,原始变量vec将不再可用
    // 下面的代码会导致编译错误,因为vec的所有权已经被闭包接管
    // println!("{:?}", vec); // 错误:vec已经移动

    print_vec(); // 输出: 1 2 3

    // 由于vec的所有权已经被闭包接管,我们不能再访问vec
    // 但我们可以在闭包内部访问它,因为闭包拥有它的所有权
}

5. 示例

fn main() {
    let x = 10;

    // 定义一个闭包,它捕获了变量x(不可变捕获)
    let add_x = |y| x + y;

    println!("add_x(5) = {}", add_x(5)); // 输出: add_x(5) = 15

    // 定义一个闭包,它以可变方式捕获外部变量(需要显式地标记为mut)
    let mut counter = 0;
    let increment = || {
        counter += 1;
        counter
    };

    println!("increment() = {}", increment()); // 输出: increment() = 1
    println!("increment() = {}", increment()); // 输出: increment() = 2

    // 闭包作为函数参数
    let numbers = vec![1, 2, 3, 4, 5];
    let doubled = numbers.iter().map(|&x| x * 2).collect::<Vec<_>>();
    println!("{:?}", doubled); // 输出: [2, 4, 6, 8, 10]
}

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

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

相关文章

openGauss开源数据库实战十八

文章目录 任务十八 openGauss逻辑结构:构:用户和权眼管理任务目标实施步骤一、准备工作二、用户和角色管理1.使用CREATE USER语句创建用户2.使用CREATE ROLE语句创建用户3.删除用户和角色 三、权限管理1.系统权限清理工作 任务十八 openGauss逻辑结构:构:用户和权眼管理 任务目…

Scratch游戏推荐 | 我的世界:平台冒险——像素世界的全新挑战! ⛏️

&#x1f3ae; Scratch游戏推荐 | 我的世界&#xff1a;平台冒险——像素世界的全新挑战&#xff01; ⛏️&#x1f30d; 今天给大家推荐一款精彩绝伦的Scratch平台冒险游戏——《我的世界&#xff1a;平台冒险 – 第二章》&#xff01;由atomicmagicnumber制作&#xff0c;这…

【java-数据结构篇】揭秘 Java LinkedList:链表数据结构的 Java 实现原理与核心概念

我的个人主页 我的专栏&#xff1a;Java-数据结构&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 目录 1. Java LinkedList 基础 1.1 LinkedList 简介 1.2 LinkedList 的实现原理 1.3 LinkedList 与 ArrayList 的区别 2. 链表基础 2.1 链…

北斗道路运输车辆管理应用:违规驾驶行为监测、车辆编队管理、安全跟踪(车辆历史轨迹查询)、车辆动态位置数据的实时查看和管理

文章目录 场景概述解决方案应用案例合作构想场景概述 面向旅游大巴车、危险品运输车及重型载货运输车等车辆,利用北斗定位导航服务,结合互联网通信技术,实现车辆安全驾驶管理与调度,有效降低道路事故发生风险,提升道路运输管理水平及车辆调度能力。 解决方案 在车辆上安…

【ABAP——DAILOG_2】

文章目录 使用Tabstrip控件实现分页签效果标签页的修改使用Table Control控件实现表单输出表格控件使用向导创建Table ControlTable Control列的修改 用户通过界面输入数据&#xff0c;数据通过屏幕控件传递到ABAP/4程序中的变量&#xff0c;程序在PBO中准备数据并显示界面&…

资料文件夹转移工具5.2.3 |快速转移到D盘,释放C盘空间

这是一款支持将C盘的常用文件夹转移到其他磁盘分区的工具&#xff0c;提供仅变目录、复制资料和转移资料三种转移方式。该工具完全免费&#xff0c;单文件免安装&#xff0c;大小仅为546KB&#xff0c;非常适合需要释放C盘空间的用户。 大小&#xff1a;546KB 下载地址&#…

使用STM32CubeMX配置串口各种功能

使用STM32CubeMX配置串口各种功能 STM32CubeMX软件的安装接收空闲中断STM32CubeMX配置1.新建工程2. 选择芯片3. 选择时钟和下载方式4. 配置串口5.设置工程消息6.生成代码7.修改生成的代码 空闲中断DMA转运STM32CubeMX配置4.配置串口5.设置工程消息6.生成代码7.修改生成的代码 S…

Javascript中DOM操作和事件监听综合练习 (具备三种功能的轮播图案例)

#如何去实现图片轮播效果图&#xff0c;通过创建一个基本的 HTML 页面结构&#xff0c;包含用于展示轮播图片的区域、左右切换箭头以及放置轮播图片的容器。# 整体架构 一、CSS 样式 接下来创建一个 styles.css 文件来设置页面的样式&#xff0c;让轮播效果看起来更美观。定义…

无人设备遥控器之防水性能篇

无人设备遥控器的防水性能是评估其耐用性和适应不同环境能力的重要指标。随着无人设备技术的不断发展&#xff0c;越来越多的遥控器在设计时融入了防水元素&#xff0c;以满足用户在不同天气条件下的使用需求。 一、防水等级与标准 无人设备遥控器的防水性能通常通过防水等级来…

【JAVA】Java入门 - 循环结构进阶

第1关 for循环的进阶使用-嵌套循环&#xff08;1&#xff09; 第2关 for循环的进阶使用-嵌套循环&#xff08;2&#xff09; 第3关 99乘法表 第4关 综合练习之ATM取款机 第5关 选择题 D、BC、B

【AI系统】AI 编译器后端优化

AI 编译器后端优化 AI 编译器分为多层架构&#xff0c;最顶层由各种 AI 训练框架编写的神经网络模型架构&#xff0c;一般由 Python 编写&#xff0c;常见的 AI 训练框架有 PyTorch、MindSpore、PaddlePaddle 等。在导入 AI 编译器时需要用对应框架的 converter 功能转换为 AI…

力扣 三角dp

动态规划基础题&#xff0c;当前所在元素来自上一行的两列的值。 题目 从图可以看出&#xff0c;每一行的第一个数与最后一个数都是1&#xff0c;然后中间的数是来自它左上方和右上方的数的和。当然并不是要打印这个三角形的形状&#xff0c;因此可以想到正常的打印方式应该是…

Oracle检查加强版本

支持更丰富了&#xff0c;代码也更乱了 #!/bin/bash## 实例个数 告警日志 实例状态 会话 活动会话 锁 集群状态 服务状态 磁盘空间 侦听日志 ## 单机、RAC Linux、AIX 11g、19c、23ai ## 依赖adrci配置正常&#xff0c;也可以改为 getAlert() ## ver 1.2case uname inAIX)ps…

RoBERTa- 稳健优化的 BERT 预训练模型详解

一、引言 自 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;问世&#xff0c;预训练语言模型在自然语言处理&#xff08;NLP&#xff09;领域掀起革命浪潮&#xff0c;凭卓越表现大幅刷新诸多任务成绩。RoBERTa 承继 BERT 架构&#x…

【流程图】各元素形状和含义

判定、文档、数据、数据库、流程处理节点 矩形 - 动词 平行四边形 - 图像 下波浪 - 数据 图片来源http://baike.cu12.com/bkss/62449.shtml

「Mac畅玩鸿蒙与硬件41」UI互动应用篇18 - 多滑块联动控制器

本篇将带你实现一个多滑块联动的控制器应用。用户可以通过拖动多个滑块&#xff0c;动态控制不同参数&#xff08;如红绿蓝三色值&#xff09;&#xff0c;并实时显示最终结果。我们将以动态颜色调节为例&#xff0c;展示如何结合状态管理和交互逻辑&#xff0c;打造一个高级的…

PyQt6 开发基础

<?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Form</class><widget class"QWidget" name"Form"><property name"geometry"><rect><x>0<…

Kafka如何保证消息可靠?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka如何保证消息可靠&#xff1f;】面试题。希望对大家有帮助&#xff1b; Kafka如何保证消息可靠&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka通过多种机制来确保消息的可靠性&#xff0c;主要包…

pytest(二)excel数据驱动

一、excel数据驱动 excel文件内容 excel数据驱动使用方法 import openpyxl import pytestdef get_excel():excel_obj openpyxl.load_workbook("../pytest结合数据驱动-excel/data.xlsx")sheet_obj excel_obj["Sheet1"]values sheet_obj.valuescase_li…

类和对象(中)(类的默认成员函数)+日期类实现

1.类的默认成员函数 默认成员函数就是用户没有显示实现&#xff0c;编译器会自动生成的成语函数称为默认成员函数。一个类&#xff0c;我们不写的情况下编译器会默认生成6个默认成员函数。C11后还增加了两个默认成员函数&#xff0c;移动构造和移动赋值&#xff08;这一节暂时…