当前位置: 首页 > 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;适用于带有大量细节的图像编码&…...

阿里云代理商:OpenClaw 技能安全部署指南与高口碑扩展精选

在集成任何 OpenClaw 第三方功能模块前&#xff0c;安全防护是首要环节。核心流程是借助官方安全审查工具&#xff0c;预先扫描潜在威胁&#xff0c;避免因加载恶意模块引发的数据泄漏或设备隐患。1. 核心安防工具部署优先部署 skill-vetting 安全扫描工具&#xff08;OpenClaw…...

一个防止GPT“降智”的简单方法

GPT客户端容易“降智”&#xff1f;教你一个简单解决办法 正文 最近一直感觉 GPT 手机客户端有点“降智”&#xff0c;回答质量不太稳定。 后来我拿同一账号做了对比&#xff0c;发现用手机浏览器登录网页版时&#xff0c;整体会正常不少&#xff0c;所以来给大家分享一下。 我…...

忍者像素绘卷效果展示:云端画布背景+金橙配色+浮雕UI真实渲染效果

忍者像素绘卷效果展示&#xff1a;云端画布背景金橙配色浮雕UI真实渲染效果 1. 视觉风格惊艳呈现 忍者像素绘卷带来了全新的视觉体验&#xff0c;将传统像素艺术与现代设计理念完美融合。这款基于Z-Image-Turbo深度优化的图像生成工具&#xff0c;创造了一个明亮通透的创作环…...

opencode令牌分析插件使用:API调用监控部署教程

opencode令牌分析插件使用&#xff1a;API调用监控部署教程 1. 引言&#xff1a;为什么需要API调用监控&#xff1f; 当你使用AI编程助手时&#xff0c;是否曾经遇到过这些问题&#xff1a;不知道模型调用了多少次API、不清楚每次调用消耗了多少token、无法监控API调用的性能…...

别只埋头改Bug!从Flutter高德地图鸿蒙适配,聊聊跨平台插件架构设计的最佳实践

从Flutter高德地图鸿蒙适配看跨平台插件架构设计的黄金法则 当Flutter遇上鸿蒙&#xff0c;开发者们既兴奋又忐忑。兴奋的是跨平台开发框架与国产操作系统的强强联合&#xff0c;忐忑的是两者结合带来的技术适配挑战。去年我们团队在将高德地图SDK集成到Flutter鸿蒙应用时&…...

Intv_AI_MK11 服务端错误处理:全面应对 403 Forbidden 等常见 HTTP 状态码

Intv_AI_MK11 服务端错误处理&#xff1a;全面应对 403 Forbidden 等常见 HTTP 状态码 1. 为什么需要关注API错误处理 在调用Intv_AI_MK11这类AI服务API时&#xff0c;开发者经常会遇到各种HTTP状态码返回。这些状态码就像是服务端给你的"小纸条"&#xff0c;告诉你…...

OpenClaw二次开发指南:Qwen3.5-9B模型适配与API扩展

OpenClaw二次开发指南&#xff1a;Qwen3.5-9B模型适配与API扩展 1. 为什么需要二次开发OpenClaw&#xff1f; 去年冬天&#xff0c;当我第一次尝试用OpenClaw对接本地部署的Qwen3.5-9B模型时&#xff0c;遇到了几个棘手问题&#xff1a;模型返回的JSON格式与框架预期不符、长…...

AI绘图小说配图批量生成 小说插图制作神器 小说配图 动漫图片生成 低配显卡可用 解决图片一致性的问题 生成的图片一致性 可控

简介说明 AI绘图小说配图批量生成 小说插图制作神器 小说配图 动漫图片生成 低配显卡可用 把常见的出图流程整理成更容易操作、更适合生产使用的工作台&#xff0c;且支持低配显卡稳定运行&#xff0c;无需升级硬件即可流畅出图。 它可以帮助用户把“启动服务、填写提示词、切…...

数据库表的性能优化过程

问题背景做一个数据库表查看、标注与分析的工具软件。是数据库中表的信息&#xff08;information_schema.tables&#xff09;&#xff1b;是的数据字典文档&#xff0c;存储在本地文件中&#xff1b;是对的额外标注信息&#xff0c;存储在另一个数据库中。每一条&#xff0c;最…...

线性结构之链表[基于郝斌课程]

每个结点只有一个前续结点每个结点只有一个后续结点首结点没有前续结点尾结点没有后续结点专业术语&#xff1a;首结点&#xff1a;第一个有效结点&#xff0c;存放第一个有效数据尾结点&#xff1a;最后一个有效结点&#xff0c;存放最后一个有效数据头结点&#xff1a;在首结…...