当前位置: 首页 > news >正文

rust 闭包函数

函数有自己的类型,可以像使用基础类型一样使用函数,包括将函数保存在变量中、保存在 vec 中、声明在结构体成员字段中。闭包函数也是函数,也有自己的类型定义。不过,函数实际上是指针类型,在 rust 所有权中属于借用的关系。

我们声明一个 Vec 对象集,并使用闭包函数做排序。接下来我们自定义一个 City 结构体类型,Vec 中的每个元素都是 City 类型,后面会根据结构体中的 population 属性做排序。

#[derive(Debug)]
struct City {name: String,population: i64,country: String,
}

我们初始化 cities 变量,并向其中依次追加 3 个元素。vec 追加元素使用 push 函数,push 过程也会触发底层数组的扩容。rust 也提供了初始化指定 vec 容量的函数 with_capacity。

fn main() {let mut cities: Vec<City> = vec![];cities.push(City {name: ("上海".to_string()),population: (123i64),country: ("China".to_string()),});cities.push(City {name: ("北京".to_string()),population: (12i64),country: ("China".to_string()),});cities.push(City {name: ("广州".to_string()),population: (124i64),country: ("China".to_string()),});sort_cities(&mut cities);println!("{:?}", cities)
}

sort_cities 算是这篇文章的关键函数了,函数内部使用到了闭包。想要彻底明白下面的逻辑,首先要了解 sort_by_key 函数,这个函数的入参是一个闭包函数。

fn sort_cities(cities: &mut Vec<City>) {cities.sort_by_key(|city| -city.population);
}

声明中的 &mut self 表示方法能够可变地借用 self 实例,支持对它进行修改。闭包函数的类型是 FnMut(&T),返回的类型需要满足 Ord 约束。从声明中可以看出,闭包函数是有类型的,同时,返回的类型必须是可排序的。

在这里插入图片描述

代码部分,闭包函数的写法特别简单,两个竖线是闭包函数识别的标志。尽管闭包函数要求有返回值,但代码中并没有体现,都是 rust 自己默认推断实现的。

我们尝试对代码部分的闭包声明做写法上的调整,下面的闭包声明都是相同的。

// 加了代码块
fn sort_cities(cities: &mut Vec<City>) {cities.sort_by_key(|city| {-city.population});
}
// 加了入参声明
fn sort_cities(cities: &mut Vec<City>) {cities.sort_by_key(|city: &City| -city.population);
}
// 加了返回值声明
fn sort_cities(cities: &mut Vec<City>) {cities.sort_by_key(|city| -> i64 { -city.population });
}

闭包引用对象的所有权

在闭包函数体中使用外部的变量,会导致外部变量的所有权发生变更吗?如果是 go 语言,外部变量在闭包中是通过引用来访问的。具体到 rust 语言上,我们可以通过自定义闭包函数验证一番。

我们在原代码基础上做了简化,is_long_name 函数体中直接访问外部变量 sh,并将 sh 的名字重新赋值一个新的变量 name。编译器检测到 sh.name 发生了所有权转移,编译失败。

fn main() {let sh = City {name: ("上海".to_string()),population: (123i64),country: ("China".to_string()),};let is_long_name = || -> bool {let name = sh.name;if name.len() > 2 {true} else {false}};is_long_name();println!("{:?}", sh);
}

在这里插入图片描述

在闭包声明的开头,大家也看到过 move 关键字。那么,这个 move 是用来解决什么问题的呢?

针对这个例子,我们专门在闭包内对 sh.name 重新做了赋值运算,变量所有权发生转移也符合认知。那么,我们现在直接使用 sh.name 进行长度判断,对应截图中的第 13 行代码。左右差异点只有:右边的闭包声明中追加生 move 关键字。

在这里插入图片描述

在这里插入图片描述

rust 中闭包取得数据有两种方式:转移和借用。move 会导致使用到的外部变量发生所有权转移。右边的例子中,闭包中的变量 sh.name 的所有权就发生了转移,导致编译失败。

相关文章:

rust 闭包函数

函数有自己的类型&#xff0c;可以像使用基础类型一样使用函数&#xff0c;包括将函数保存在变量中、保存在 vec 中、声明在结构体成员字段中。闭包函数也是函数&#xff0c;也有自己的类型定义。不过&#xff0c;函数实际上是指针类型&#xff0c;在 rust 所有权中属于借用的关…...

MySQL 实现分库和分表的备份 2023.7.29

1、分库备份 [rootlocalhost mysql-backup]# cat db_bak.sh #!/bin/bash k_userroot bak_password123456 bak_path/root/mysql-backup/ bak_cmd"-u$bak_user -p$bak_password" exc_db"Database|information_schema|mysql|performance_schema|sys" dbname…...

20230728----重返学习-跨域-模块化-webpack初步

day-122-one-hundred-and-twenty-two-20230728-跨域-模块化-webpack初步 跨域 跨域 为什么要跨域&#xff1f; 浏览器为了安全&#xff0c;不能让我们的html文件可以随意引用别的服务器中的文件&#xff0c;只允许我们的html或js文件中&#xff0c;请求我们自己服务器。这个…...

[SQL挖掘机] - 多表连接: union all

介绍: sql中的union all是用于合并两个或多个select语句的结果集的操作符。与union不同的是&#xff0c;union all不会自动去除重复的行&#xff0c;它会简单地将多个查询的结果集合并在一起&#xff0c;包括重复的行。 用法: union all的基本语法如下&#xff1a; select_…...

TypeError: run() got an unexpected keyword argument ‘hide_label‘ yolov5最新版本报错

报错展示 解决方法 把detect.py中的如上部分的 --hide-label改为 --hide-labels&#xff0c;成功解决....

什么是Java中的集成测试?

Java中的集成测试&#xff08;Integration Test&#xff09;是一种测试方法&#xff0c;用于测试多个模块或组件之间的交互和集成。在Java中&#xff0c;集成测试通常使用单元测试框架&#xff08;如JUnit&#xff09;编写和运行。 对于初学者来说&#xff0c;集成测试可能有些…...

打卡力扣题目二

#左耳听风 ARST 打卡活动重启# 目录 一、问题 二、 解题方法一 三、enumerate函数介绍 关于 ARTS 的释义 —— 每周完成一个 ARTS&#xff1a; ● Algorithm: 每周至少做一个 LeetCode 的算法题 ● Review: 阅读并点评至少一篇英文技术文章 ● Tips: 学习至少一个技术技巧 …...

【Qt】QML-02:QQuickView用法

1、先看demo QtCreator自动生成的工程是使用QQmlApplicationEngine来加载qml文件&#xff0c;下面的demo将使用QQuickView来加载qml文件 #include <QGuiApplication> #include <QtQuick/QQuickView>int main(int argc, char *argv[]) {QGuiApplication app(argc,…...

【IDEA】idea不自动生成target

文章目录 1. 不生成target2. 仅部分文件不生成target2.1. 一般原因就是资源没有设置2.2. 配置编译src/main/java文件夹下的资源文件2.3. 清理缓存&#xff08;王炸&#xff09; 3. 参考资料 本文描述idea不生成target的几种情况以及处理方法 1. 不生成target 像下图这样根本就…...

从官网认识 JDK,JRE,JVM 三者的关系

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ JVM 是一些大厂面试必问点&#xff0c;要想解决 OOM、性能调优方面的问题&#xff0c;掌握 JVM 知识必不可少&#xff0c;从今天开始&#xff0c;将为大家介绍 JVM 的常用知…...

python 将pdf文件转图片

有小伙伴问了怎么将 pdf文件转图片的问题&#xff0c;我百度了一波儿&#xff0c;搞了以下python代码给他封装成exe工具了。 中途打包踩了个坑&#xff0c;python进程池的问题&#xff0c;本地运行没啥问题&#xff0c;打包好的exe文件双击就会使电脑内存爆破卡死&#xff0c;…...

js原型以及原型链

目录 原型隐式原型显式原型constructornew操作符 重写原型对象原型链继承原型链继承借用构造函数继承组合构造继承 原型继承寄生继承组合寄生继承 原型继承关系 原型 在JavaScript中&#xff0c;每个对象都有一个内置属性[[prototype]]&#xff0c;这个属性指向一个另一个对象…...

Java面向对象编程实战详解(图书管理系统示例)

文章目录 面向编程概念图书管理系统示例需求分析设计阶段编码实现创建目录结构Book类的编码BookList类的编码User类的编码AdminUser类的编码NormalUser类的编码启动类的编写具体的操作实现IOperation接口新增图书的实现借阅图书的实现删除图书的实现显示图书的实现查找图书的实…...

ubuntu设置主机ip

ubuntu 设置ip sudo dhclient -r enp67s0 # 是你的网卡&#xff0c;可以通过ifconfig 查&#xff0c;比如enp0 sudo ifconfig enp67s0 192.168.1.114 netmask 255.255.255.0 Ubuntu显示有线网已连接但无法上网&#xff0c;已经确认网口、交换机&#xff08;路由器&#xff…...

CleanMyMac X4.14.1中文版如何清理 Mac系统?CleanMyMac 真的能断网激活吗?

CleanMyMac X4.14.1中文版如何清理 Mac系统&#xff1f;Mac系统在使用过程中都会产生大量系统垃圾&#xff0c;如不需要的系统语言安装包&#xff0c;视频网站缓存文件&#xff0c;mac软件卸载残留的注册表等。 随着时间推移&#xff0c;mac系统垃圾就会越来越多&#xff0c;电…...

详细介绍 React 中如何使用 redux

在使用之前要先了解它的配套插件&#xff1a; 在React中使用redux&#xff0c;官方要求安装其他插件 Redux Toolkit 和 react-redux Redux Toolkit&#xff1a;它是一个官方推荐的工具集&#xff0c;旨在简化 Redux 的使用和管理。Redux Toolkit 提供了一些提高开发效率的工具…...

VLOOKUP多条件查询

LOOKUP(1,0/((A3:A15A18)*(C3:C15C18)),F3:F15)...

分页插件Mybatis

<plugins><!-- com.github.pagehelper为PageHelper类所在包名 --><plugin interceptor"com.github.pagehelper.PageInterceptor"><!-- 配置方言:告诉分页插件使用底层数据库是什么--><property name"helperDialect" value"…...

AXI协议之AXILite开发设计(四)—Block Design使用

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 2、AXI interconnect互联组件的使用…...

音视频——帧内预测

H264编码(帧内预测) 在帧内预测模式中&#xff0c;预测块P是基于已编码重建块和当前块形成的。对亮度像素而言&#xff0c;P块用于44子块或者1616宏块的相关操作。44亮度子块有9种可选预测模式&#xff0c;独立预测每一个44亮度子块&#xff0c;适用于带有大量细节的图像编码&…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...