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

[Rust] 可迭代类型, 迭代器, 如何正确的创建自定义可迭代类型

在 Rust 中, for 语句的执行依赖于类型对于 IntoIterator 的实现, 如果某类型实现了这个 trait, 那么它就可以直接使用 for 进行循环.


直接实现

在 Rust 中, 如果一个类型实现了 Iterator, 那么它会被同时实现 IntoIterator, 具体逻辑是返回自身, 因为自身就是迭代器.

但是如果自身就是迭代器的话, 就意味着自身必须存储迭代状态, 例如当前迭代的位置. 如果是这样的话, 迭代器就只能被使用一次. 况且自身直接被传入 into_iter 方法后, 所有权被转移, 该对象就无法被再次使用了.

定义类型本身:

struct IntRange {current: i32,step: i32,end: i32
}

直接为其实现迭代器:

impl Iterator for IntRange {type Item = i32;fn next(&mut self) -> Option<Self::Item> {if self.current == self.end {return None;} else {let current = self.current;self.current += self.step;return Some(current);}}
}

使用该类型:

let range = IntRange { current: 0, step: 1, end: 10 };
for value in range {println!("v: {}", value);
}

所以结论是, 如果你的类型是一次性用品, 你可以直接对其实现 Iterator


手动实现迭代器

如果你向手动实现类似于容器的东西, 那么它当然不是一次性的. 我们应该仿照 Rust 中对切片的迭代器实现.

  1. 同时实现会转移所有权和不会转移所有权的两个迭代器
  2. self&self 都实现 IntoIterator, 这样就可以做不转移所有权的迭代了

类型本身:

struct IntRange {step: i32,end: i32
}

两个迭代器:

struct IntRangeIter<'a> {range: &'a IntRange,current: i32,
}struct IntRangeIntoIter {range: IntRange,current: i32,
}

两个迭代器实现:

impl Iterator for IntRangeIter<'_> {type Item = i32;fn next(&mut self) -> Option<Self::Item> {if self.current == self.range.end {return None;} else {let current = self.current;self.current += self.range.step;return Some(current);}}
}impl Iterator for IntRangeIntoIter {type Item = i32;fn next(&mut self) -> Option<Self::Item> {if self.current == self.range.end {return None;} else {let current = self.current;self.current += self.range.step;return Some(current);}}
}

实现返回两种迭代器的 IntoIterator:

impl<'a> IntoIterator for &'a IntRange {type Item = i32;type IntoIter = IntRangeIter<'a>;fn into_iter(self) -> Self::IntoIter {IntRangeIter {range: self,current: 0}}
}impl IntoIterator for IntRange {type Item = i32;type IntoIter = IntRangeIntoIter;fn into_iter(self) -> Self::IntoIter {IntRangeIntoIter {range: self,current: 0}}
}

使用它:

let range = IntRange { step: 1, end: 10 };// 可以使用引用来进行 for 循环
for value in &range {println!("v: {}", value);
}// 也可以直接对其进行 for 循环
for value in range {println!("v: {}", value);
}

切片对迭代的实现

我们知道, Rust 的切片有一个 iter 方法, 其实它就相当于对当前切片的引用调用 into_iter.

其实, 在调用切片引用的 into_iter 方法时, 本质上就是调用的其 iter 方法. 方法的实现是在 iter 内的.

let v = vec![1, 2, 3];// 下面两个调用是等价的
let iter1 = v.iter();
let iter2 = (&v).into_iter();

如果你希望实现迭代变量可变的迭代器, 还可以为 &mut T 实现 into_iter, 当然, Rust 内部对于切片的实现, 也是这样的:

let mut v = vec![1, 2, 3];// 下面两个调用是等价的
let mutIter = v.iter_mut();
let mutIter = (&mut v).into_iter();

总结

两种类型:

  1. 对于一次性使用的类型, 可以直接对其实现迭代器 trait.

  2. 对于容器, 不应该对容器本身直接实现迭代器, 而是应该单独创建迭代器类型, 然后对其本身实现 IntoIterator

为了方便用户使用, 调用之间的实现应该是这样:

  1. 实现 TIntoIterator
  2. 实现 &Titer 函数, 返回借用的迭代器.
  3. 实训 &mut Titer_mut 函数, 返回可变借用的迭代器.
  4. &T&mut T 实现 into_iter 函数, 并在内部调用刚刚实现的 iteriter_mut 函数.

这样, 用户就可以直接调用 iter 方法获得借用的迭代器, 然后使用 map, filter 等方法进行集合的复杂操作了

相关文章:

[Rust] 可迭代类型, 迭代器, 如何正确的创建自定义可迭代类型

在 Rust 中, for 语句的执行依赖于类型对于 IntoIterator 的实现, 如果某类型实现了这个 trait, 那么它就可以直接使用 for 进行循环. 直接实现 在 Rust 中, 如果一个类型实现了 Iterator, 那么它会被同时实现 IntoIterator, 具体逻辑是返回自身, 因为自身就是迭代器. 但是如…...

MySQL中,text,mediumtext, 和 longtext字符类型

需求 由于项目需要&#xff0c;需要在mysql数据库&#xff0c;储存长文本&#xff0c;长文本格式可能为markdown也可能为html。 思路 测试存入html时&#xff0c;字符类型为varcar 255。很明显字符长度达不到要求。数据库抛错&#xff0c;修改字符类型 解决方案 将原本的字…...

网页开发 JS基础

目录 JS概述 基本语法 数据类型内置方法 DOM对象 查找标签 绑定事件 操作标签 jQuery 查找标签 绑定事件 操作标签 Ajax请求 数据接口 前后端分离 ajax的使用 JS概述 一门弱类型的编程语言,属于基于对象和基于原型的脚本语言. 1 直接编写<script>console…...

如何在财税行业查找批量客户?

现在市场上代记账公司也不算少&#xff0c;做过这行的都知道&#xff0c;最初呢行业竞争不强&#xff0c;都是靠地推、老客户转介绍&#xff0c;或者长期以往的蹲守各个地区的工商注册服务中心&#xff0c;找那些才注册企业的老板或者创业者。但是&#xff0c;随着市场经济的发…...

IntelliJ IDEA详细完整安装教程

IntelliJ IDEA 是一款强大的Java集成开发环境&#xff0c;以下是安装和使用教程&#xff1a; 1. 下载IntelliJ IDEA&#xff1a;访问JetBrains官网&#xff08;jetbrains.com&#xff09;&#xff0c;点击“Download”按钮&#xff0c;选择适合自己操作系统的版本进行下载。 2.…...

【.NET Core】Linq查询运算符(一)

【.NET Core】Linq查询运算符&#xff08;一&#xff09; 文章目录 【.NET Core】Linq查询运算符&#xff08;一&#xff09;一、概述二、筛选数据三、投影运算3.1 Select 3.2 SelectMany3.3 Zip3.4 Select 与 SelectMany 四、Set&#xff08;设置&#xff09;运算4.1 Distinct…...

Python sorted函数及用法以及如何用json模块存储数据

Python sorted函数及用法 sorted() 函数与 reversed() 函数类似&#xff0c;该函数接收一个可迭代对象作为参数&#xff0c;返回一个对元素排序的列表。 在交互式解释器中测试该函数&#xff0c;可以看到如下运行过程&#xff1a; >>> a [20, 30, -1.2, 3.5, 90, 3.…...

使用opencv将sRGB格式的图片转换为BT.2020格式【sRGB】【BT.2020】

将sRGB格式的图片转换为BT.2020格式涉及到两个步骤&#xff1a;首先将sRGB转换到线性RGB&#xff0c;然后将线性RGB转换到BT.2020。这是因为sRGB图像通常使用伽马校正&#xff0c;而BT.2020工作在线性色彩空间中。 从sRGB到线性RGB&#xff1a;sRGB图像首先需要进行伽马校正解码…...

聊天注意事项

聊天成功的核心就是双方都能舒服 有些人不会聊天是缺乏引导性 聊天聊两句话就没了 聊天要把话题引导向对方 从倾诉者变为倾听者 才能不断交流 沟通不是一个人的独角戏 每个人都渴望被理解 要注意倾听别人说的话 不要只顾自己说一大堆&#xff0c;别人都瞌睡了 不要查户口式问…...

12.5 作业

1&#xff0c; 以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff0c;动物园里有…...

深入理解指针3

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起继续深入学习指针&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff01;&#xff01;&#xff01; 话不多说&am…...

大数据环境下在线考试系统安全策略研究

摘 要 随着云计算、物联网、电子商务、企业信息化等的飞速发展&#xff0c;以及智能终端和各种检测、感应设备的普及和建设&#xff0c;全球逐渐进入信息化、网络化&#xff0c;由此产生了指数爆炸般的数据增长&#xff0c;一个大规模生产、分享和应用的数据的时代正在开启&am…...

Python中程序的异常处理

Python程序一般对输入有一定要求&#xff0c;担当实际输入不满足程序要求时&#xff0c;可能会产生程序的运行错误。Python语言使用的保留太容易try和except进行异常处理&#xff01; try: 语句块1 except: 语句块2 语句块1是正常执行的程序内容&#xff0c;当这个语句块发生异…...

有趣的代码——有故事背景的程序设计3

这篇文章再和大家分享一些有“背景”的程序设计&#xff0c;希望能够让大家学到知识的同时&#xff0c;对编程学习更感兴趣&#xff0c;更能在这条路上坚定地走下去。 目录 1.幻方问题 2.用函数打印九九乘法表 3.鸡兔同笼问题 4.字数统计 5.简单选择排序 1.幻方问题 幻方又…...

聚观早报 |国行PS5轻薄版开售;岚图汽车11月交付7006辆

【聚观365】12月2日消息 国行PS5轻薄版开售 岚图汽车11月交付7006辆 比亚迪推出12月限时优惠 特斯拉正式交付首批Cybertruck 昆仑万维发布「天工 SkyAgents」平台 国行PS5轻薄版开售 索尼最新的PlayStation5主机&#xff08;CFI-2000型号组-轻薄版&#xff09;国行版本正…...

Kafka 保证消息消费全局顺序性

当有消息被生产出来的时候&#xff0c;如果没有指定分区或者指定 key &#xff0c;那么消费会按照【轮询】的方式均匀地分配到所有可用分区中&#xff0c;但不一定按照分区顺序来分配 我们知道&#xff0c;在 Kafka 中消费者可以订阅一个或多个主题&#xff0c;并被分配一个或多…...

3分钟在CentOS 7上离线安装Docker

在CentOS 7上离线安装Docker的详细步骤如下&#xff1a; 环境检查和准备 检查内核版本&#xff1a;Docker要求系统为64位且内核版本至少为3.10。使用命令uname -r查看内核版本。 检查CentOS版本&#xff1a;通过命令cat /etc/redhat-release查看版本信息。 更新yum包&#xff0…...

GaussDB数据库SQL系列-触发器

目录 一、前言 二、触发器概念 三、GaussDB数据库中的触发器 1、语法格式 2、创建步骤 3、注意事项 4、附&#xff1a;表和视图上支持的触发器种类 四、GaussDB数据库中的示例 示例一、在GaussDB数据库中创建一个触发器&#xff0c;以便在插入新记录时自动将记录的创建…...

网工学习10-IP地址

一、IP地址概念 IP地址是一个32位的二进制数&#xff0c;它由网络ID和主机ID两部份组成&#xff0c;用来在网络中唯一的标识的一台计算机。网络ID用来标识计算机所处的网段&#xff1b;主机ID用来标识计算机在网段中的位置。IP地址通常用4组3位十进制数表示&#xff0c;中间用…...

二百零八、Hive——HiveSQL异常:Select查询数据正常,但SQL语句加上group by查询数据为空

一、目的 在HiveSQL的DWD层中&#xff0c;需要对原始数据进行去重在内的清洗&#xff0c;结果一开始其他数据类型的清洗工作都正常&#xff0c;直到碰到转向比数据。 一般的SQL查询有数据&#xff0c;但是加上group by以后就没数据&#xff1b; 一般的SQL查询有数据&#xf…...

春联生成模型-中文-base实战:输入‘幸福‘、‘平安‘,AI自动创作完整春联

春联生成模型-中文-base实战&#xff1a;输入幸福、平安&#xff0c;AI自动创作完整春联 1. 项目介绍与核心功能 春节贴春联是中国传统文化的重要组成部分&#xff0c;但创作一副对仗工整、寓意吉祥的春联并不容易。春联生成模型-中文-base正是为解决这个问题而开发的AI应用。…...

从数据到农田:基于YOLOv8的番茄叶片病害实时检测系统全流程实战

1. 番茄病害检测的农业痛点与技术选型 在传统农业生产中&#xff0c;番茄种植户通常需要每天巡视大棚或田间&#xff0c;用肉眼观察叶片状态来判断病害情况。这种方法存在三个致命缺陷&#xff1a;一是人工检查效率低下&#xff0c;一个标准大棚需要30-40分钟才能完成全面检查&…...

英文版Linux系统的安装

1.下载vmware workstation pro2.准备好ISO镜像3.电脑保证有充分内存二、创建新的虚拟机1.使用自定义类型的配置&#xff08;高级&#xff09;2.硬件兼容性选择默认即可3.选择客户机操作系统&#xff1a;系统&#xff1a;Linux 版本&#xff1a;Red Hat Enterprise Linux 9 …...

111 OCR文字识别技术实战

OCR文字识别技术实战 本文深入剖析OCR文字识别技术在企业级应用中的完整实现方案,从服务选型、图片预处理、API调用到识别准确率优化,结合实际业务场景提供可落地的技术方案。 1 OCR服务选型 为什么需要OCR技术? 在企业级应用中,大量的业务数据以图片、PDF等非结构化形式存在…...

一分钟学会AI修图:InstructPix2Pix新手入门必看操作视频配套教程

一分钟学会AI修图&#xff1a;InstructPix2Pix新手入门必看操作视频配套教程 你是不是也遇到过这种情况&#xff1f;拍了一张不错的照片&#xff0c;但总觉得哪里差了点意思——背景太乱、光线不好、或者想给朋友P个有趣的造型。一想到要打开复杂的修图软件&#xff0c;研究各…...

Phi-3 Mini 128K部署教程:GPU监控(nvidia-smi)与性能瓶颈定位方法

Phi-3 Mini 128K部署教程&#xff1a;GPU监控&#xff08;nvidia-smi&#xff09;与性能瓶颈定位方法 1. 为什么部署后还要关心GPU&#xff1f; 你可能已经成功部署了Phi-3 Forest Laboratory&#xff0c;看着它流畅地回答问题&#xff0c;感觉一切都很完美。但当你开始处理更…...

AudioSeal Pixel Studio参数详解:detector threshold动态调整对FP/FN影响分析

AudioSeal Pixel Studio参数详解&#xff1a;detector threshold动态调整对FP/FN影响分析 1. 核心概念与背景 AudioSeal Pixel Studio作为专业级音频水印工具&#xff0c;其核心价值在于平衡水印检测的准确性与误判率。检测器阈值&#xff08;detector threshold&#xff09;…...

科技中介如何优化技术转移服务流程?

观点作者&#xff1a;科易网-AI技术转移与科技创新数智化服务平台一、现状概述&#xff1a;成效与短板 在数智化转型浪潮下&#xff0c;科技成果转化正经历深刻变革。传统科技中介服务模式以线下对接、人工匹配为主&#xff0c;存在信息不对称、响应滞后、转化效率低等问题。尽…...

好用的玉柴柴油发电机组哪个服务好

扬州量子电力设备有限公司&#xff1a;为玉柴发电机组提供专业的技术服务与方案解析玉柴柴油发电机组在长期高负荷运行下的功率稳定性与燃油经济性平衡&#xff0c;是当前行业普遍面临的技术挑战。这不仅关系到设备的使用寿命&#xff0c;更直接影响运营成本与供电可靠性。针对…...

第二章 第一性原理:底层结构——公理、推导与边界

第二章 第一性原理:底层结构——公理、推导与边界 一、开篇:为什么你的"第一性原理"总是失效? 很多人听完马斯克的故事,热血沸腾地宣称自己也要用第一性原理思考。结果却是: 拆解问题很彻底,推导过程很严密,最终结论却与现实严重脱节。要么执行不下去,要么…...