Rust语言之迭代器
文章目录
- Rust迭代器
- Rust迭代器的实现
- Iterator特型
- IntoIterator特型
- for循环与迭代器
- 迭代器类型
- 再看for循环
- 实现自定义迭代器
- 方式一
- 方式二
- 相关参考
Rust迭代器
Rust语言内置了迭代器模式,用于实现对一个项的序列进行特定的处理,通常配合for循环使用。当我们使用for...in遍历一个容器向量时,其实就是在使用迭代器:
let vec = vec![1, 2, 3];for val in vec {println!("{} ", val);
}
为了方便开发者的使用,for...in表达式隐藏了很多迭代器的使用和实现细节,这些我们将在后面慢慢看到。
Rust迭代器的实现
Rust迭代器的实现基于两个关键的特型:Iterator和IntoIterator,在Rust中,迭代器指的是任何实现std::iter::Iterator特型的值,而IntoIterator用于生成某种类型的迭代器。
Iterator特型
Rust标准库中Iterator特型定义如下:
trait Iterator {type Item; // 产生值的类型fn next(&mut self) -> Option<Self::Item>; // 迭代器... //其它迭代器方法
}
Item是迭代器产生值的类型。next方法返回Option枚举值,当值为Some(v)时,v存储迭代器的下一个值;值为None时,表示序列终止。
IntoIterator特型
如果某种类型是可迭代的,那么它可以实现std::iter::IntoIterator特型。IntoIterator提供into_iter方法用于接收一个值,然后基于这个值返回一个迭代器。Rust标准库中IntoIterator特型定义如下:
trait IntoIterator where Self::IntoIter::Item == Self::Item {type Item; // 产生值的类型type IntoIter: Iterator; // 迭代器的类型fn into_iter(self) -> Self::IntoIter; // 返回一个迭代器
}
IntoIter是迭代器自身的类型,Item是迭代器产生值的类型。接下来,我们再来看for循环。
for循环与迭代器
for循环的语法形式如下:
for loop_variable in collection {code()
}
这里,变量collections就是实现了Iterator和IntoIterator的类型。Rust在后台会对上述代码进行扩展,因此,for循环的实际执行代码如下:
{let mut _iter = std::iter::IntoIterator::into_iter(collections);loop {match _iter.next() {Some(loop_variable) => {code()},None => break,}}
}
可以看到,for循环的本质就是使用into_iterator()方法将一些集合类型转换为迭代器,再使用next()方法逐个遍历序列。
迭代器类型
Rust中大多数集合类型提供了不止一个IntoIterator的实现,可用来产生迭代项不可变引用、可变引用或者值类型的迭代器,对应方法和描述如下表:
| 方法 | 描述 | 等价形式 |
|---|---|---|
| into_iter() | 返回一个只读不可重入迭代器,迭代器元素的类型为 T | v.into_iter() |
| iter() | 返回一个只读可重入迭代器,迭代器元素的类型为 &T | (&v).into_iter() |
| iter_mut() | 返回一个可修改可重入迭代器,迭代器元素的类型为 &mut T | (&mut v).into_iter() |
其中,要说明的是iter和iter_mut并不是属于某种特型的方法,它们是这些集合类型额外提供的方法,可以理解为是一种简化版的使用形式。
再看for循环
由于for循环会对其操作数应用into_iterator()方法,因此这三个实现就可以消费集合并取得其元素的所有权,以及支持迭代集合的不可变引用、可变引用:
for element in collection {} 等效于 for element in collection.into_iter() {} // 执行后,collection所有权会被转移,无法再访问
for element in &collection {} 等效于 for element in collection.iter() {}
for element in &mut collection {} 等效于 for element in collection.iter_mut() {}
实现自定义迭代器
Rust中实现自定义迭代器本质上就是为自定义类型实现Iterator和IntoIterator特型。
方式一
struct Counter {max: i32,// `count` tracks the state of this iterator.count: i32,
}impl Counter {fn new(max: i32) -> Counter {Counter { count: -1, max: max }}
}impl Iterator for Counter {type Item = i32;fn next(&mut self) -> Option<Self::Item> {self.count += 1;if self.count < self.max {Some(self.count)} else {None}}
}// 使用for循环遍历迭代器使用
for i in Counter::new(10) {println!("{}", i);
}
方式二
struct Counter {max: i32,// No need to track the state, because this isn't an iterator.
}impl Counter {fn new(max: i32) -> Counter {Counter { max: max }}
}impl IntoIterator for Counter {type Item = i32;type IntoIter = std::ops::Range<Self::Item>;fn into_iter(self) -> Self::IntoIter {std::ops::Range{ start: 0, end: self.max }}
}for i in Counter::new(10) {println!("{}", i);
}
相关参考
- 《Rust程序设计》
- 《Rust程序设计语言》
- Rust 迭代器 Iterator:https://www.twle.cn/c/yufei/rust/rust-basic-iterator.html
相关文章:
Rust语言之迭代器
文章目录Rust迭代器Rust迭代器的实现Iterator特型IntoIterator特型for循环与迭代器迭代器类型再看for循环实现自定义迭代器方式一方式二相关参考Rust迭代器 Rust语言内置了迭代器模式,用于实现对一个项的序列进行特定的处理,通常配合for循环使用。当我们…...
TreeSet 与 TreeMap And HashSet 与 HashMap
目录 Map TreeMap put()方法 : get()方法 : Set> entrySet() (重) : foreach遍历 : Set 哈希表 哈希冲突 : 冲突避免 : 冲突解决 ---- > 比散列(开放地址法) : 开散列 (链地址法 . 开链法) 简介 : 在Java中 , TreeSet 与 TreeMap 利用搜索树实现 Ma…...
Java围棋游戏的设计与实现
技术:Java等摘要:围棋作为一个棋类竞技运动,在民间十分流行,为了熟悉五子棋规则及技巧,以及研究简单的人工智能,决定用Java开发五子棋游戏。主要完成了人机对战和玩家之间联网对战2个功能。网络连接部分为S…...
第七十三章 使用 irisstat 实用程序监控 IRIS - 使用选项运行 irisstat
文章目录第七十三章 使用 irisstat 实用程序监控 IRIS - 使用选项运行 irisstat使用选项运行 irisstatirisstat Options第七十三章 使用 irisstat 实用程序监控 IRIS - 使用选项运行 irisstat 使用选项运行 irisstat 不带选项运行 irisstat 会生成基本报告。通常,…...
【博客619】PromQL如何实现Left joins以及不同metrics之间的复杂联合查询
PromQL如何实现Left joins以及不同metrics之间的复杂联合查询 1、场景 我们需要在PromQL中实现类似SQL中的连接查询: SELECT a.value*b.value, * FROM a, b2、不同metrics之间的复杂联合查询 瞬时向量与瞬时向量之间进行数学运算: 例如:根…...
Win11自定义电脑右下角时间显示格式
Win11自定义电脑右下角时间显示格式 一、进入附加设置菜单 1、进入控制面板,选择日期和时间 2、选择修改日期和时间 3、选择修改日历设置 4、选择附加设置 二、自定义时间显示出秒 1、在选项卡中,选时间选项卡 2、在Short time的输入框中输入H:m…...
TrueNas篇-trueNas Scale安装
安装TrueNAS Scale 在尝试trueNas core时发下可以成功安装,但是一直无法成功启动,而且国内对我遇见的错误几乎没有案例,所以舍弃掉了,而且trueNas core是基于Linux的,对Linux的生态好了很多,还可以可以在t…...
element表单搜索框与表格高度自适应
一般在后台管理系统中,表单搜索框和表格的搭配是非常常见的,如下所示: 在该图中,搜索框有五个,分为了两行排列。但根据大多数的UI标准,搜索框默认只显示一行,多余的需要进行隐藏。此时的页面被…...
MySQL使用技巧整理
title: MySQL使用技巧整理 date: 2021-04-11 00:00:00 tags: MySQL categories:数据库 重建索引 索引可能因为删除,或者页分裂等原因,导致数据页有空洞,重建索引的过程会创建一个新的索引,把数据按顺序插入,这样页面…...
七大设计原则之里氏替换原则应用
目录1 里氏替换原则2 里氏替换原则应用1 里氏替换原则 里氏替换原则(Liskov Substitution Principle,LSP)是指如果对每一个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都替换成 o2 时,程序 P…...
1行Python代码去除图片水印,网友:一干二净
大家好,这里是程序员晚枫。 最近小明在开淘宝店(店名:爱吃火锅的少女),需要给自己的原创图片加水印,于是我上次给她开发了增加水印的功能:图片加水印,保护原创图片,一行…...
Connext DDS属性配置参考大全(2)
DDSSecure安全com.rti.servcom.rti.serv.load_plugin...
一起Talk Android吧(第四百九十二回:精简版动画)
文章目录概念介绍使用方法示例代码经验总结各位看官们大家好,上一回中咱们说的例子是"动画集合:AnimatorSetBuilder",这一回中咱们说的例子是" 精简版动画"。闲话休提,言归正转,让我们一起Talk Android吧&…...
seata源码-全局事务回滚服务端源码
这篇博客来记录在发起全局事务回滚时,服务端接收到netty请求是如何处理的 1. 发起全局事务回滚请求 在前面的博客中,有说到过,事务发起者在发现分支事务执行异常之后,会提交全局事务回滚的请求到netty服务端,这里是发…...
【Vue3源码】第一章 effect和reactive
文章目录【Vue3源码】第一章 effect和reactive前言1、实现effect函数2、封装track函数(依赖收集)3、封装reactive函数4、封装trigger函数(依赖触发)5、单元测试【Vue3源码】第一章 effect和reactive 前言 今天就正式开始Vue3源码…...
C函数指针
函数指针是指向函数的指针变量。通常我们说的指针变量是指向一个整型、数组或字符型等变量,而函数指针是指向函数。函数指针可以像一般函数一样,用于调用函数、传递参数。函数指针变量的声明:typedef int (*fun_ptr)(int,int); // 声明一个指…...
2023同等学力申请硕士计算机综合国考
同等学力国考报名要开始了 2023年2月15日,中国教育考试网和“全国同等学力人员申请硕士学位管理工作信息平台”(https://tdxl.chsi.com.cn,联系服务电话:010-67410388)公布报名工作通知。考生须按照通知要求进行注册或…...
英语基础-并列句概述
什么是并列句?并列句就是用连词把独立的句子连接起来,使得句子之间产生并列的逻辑。 1. 并列句中的逻辑 1. 小明步行上学,小红骑自行车上班。 Ming goes to school on foot,and Hong goes to work by bike. 平行逻辑 2. 小红经常玩手机…...
大数据框架之Hadoop:HDFS(一)HDFS概述
1.1HDFS产出背景及定义 HDFS 产生背景 随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件…...
20230210组会论文总结
目录 【Ultra-High-Definition Low-Light Image Enhancement: A Benchmark and Transformer-Based Method】 【ShuffleMixer: An Efficient ConvNet for Image Super-Resolution】 【A Close Look at Spatial Modeling: From Attention to Convolution 】 【DEA-Net: Single i…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
