迭代器模式

自定义 Counter 结构体类型,并实现迭代器。其他语言的场景,读取数据库行数据时,使用的就是迭代器。我们使用for语言遍历数组,也是一种迭代。

结构体对象实现 Iterator trait,创建自定义的迭代器,只需要实现一个next方法的定义。它会在每次调用时返回一个包裹在Some中的迭代器元素,并在迭代器结束时返回None

Item定义为关联类型,就像是给类型起了一个别名。

struct Counter {count: u32,
}impl Counter {fn new() -> Counter {Counter { count: 0 }}
}impl Iterator for Counter {type Item = u32;fn next(&mut self) -> Option<Self::Item> {self.count += 1;if self.count < 3 {return Some(self.count);}None}
}#[test]
fn calling_next_directly() {let mut count = Counter::new();assert_eq!(count.next(), Some(1));assert_eq!(count.next(), Some(2));assert_eq!(count.next(), None);
}

这个迭代器并没有特别的地方,某种意义上它就是实现了一个接口,外部可以将这个对象当做接口来看待,最终体现在无脑适用迭代器提供的模式方法。

例子中的new方法称为关联函数associated function,将其命名为函数而不是方法,是因为它不会作用域某个具体的结构体实例,方法的参数声明中也不接受self,但它依然声明在impl块中。

new类似于构造函数,用来实例化一个新的结构体类型。通过类型名后面追加::来调用关联函数。单元测试的例子calling_next_directly声明了Counter实例并手动调用next方法。

适配器

实现了迭代器,如果只是为了手动调用next方法,那没啥意义。关键是依赖RUST提供的各种模式方法来链式处理迭代器。

迭代器抽象封装了很多处理模式,也就是迭代器适配器iterator adaptor方法,用来将现有的迭代器转换为其它不同类型的迭代器,通过链式地调用多个迭代适配器来完成一些复杂的操作。

下面的单元测试通过迭代器构造了一个[(1, 2)]元组。zip方法会在两个迭代器中任意一个返回None是结束迭代,skip跳过了第一个迭代,collect返回一个配对后值的集和。

#[test]
fn using_other_iterator_trait_methods() {let s: Vec<(u32, u32)> = Counter::new().zip(Counter::new().skip(1)).collect();println!("{:?}", s)
}

RUST正是有通过这个适配器,给我们抽象出了很多处理模式,我们通过简单的链式调用就可以实现很多复杂的能力。下面的方法介绍,也可以快速浏览官方查看。

collect方法

将一个迭代器转换为集合,只不过collect推断不出我们最终想要的类型,需要我们明确指定 collect返回值的类型。上个例子中的Vec<(u32, u32)>必须明确的指定类型,否则编译器会报错。

collect文档中还提供了另一种指定类型的方式:“turbofish::<>”,调整之后的代码会变成下面这个样子,结合编译器给出的类型提示,理解迭代器链路上上对象声明。

#[test]
fn using_other_iterator_trait_methods() {let s = Counter::new().zip(Counter::new().skip(1)).collect::<Vec<(u32, u32)>>();println!("{:?}", s)
}

在这里插入图片描述

collect返回集合的基础上还可以继续迭代,继续生成新的集合。下面的代码示例,我们基于第一次collect生成的元素[(1, 2)],重新生成一个新的集合[(2, 4)]

#[test]
fn using_other_iterator_trait_methods() {let s: Vec<(u32, u32)> = Counter::new().zip(Counter::new().skip(1)).collect::<Vec<(u32, u32)>>().iter().map(|x| (x.0 * 2, x.1 * 2)).collect();println!("{:?}", s)
}

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

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

相关文章

【全栈开发】Blitz.js与RedwoodJS

技术的不断发展是必然的。如果你仔细观察这片土地&#xff0c;你会注意到随着技术的成熟而出现的某些模式。特别是&#xff0c;开发人员一直在努力提高性能&#xff0c;简化开发过程&#xff0c;增强开发人员体验。 在本指南中&#xff0c;我们将分析两个帮助全栈应用程序世界…

航天宏图——宏图1号样例数据0.5米-5米分辨率(上海部分)

简介&#xff1a; 作为航天宏图“女娲星座”建设计划的首发卫星&#xff0c;航天宏图-1号可获取0.5米-5米的分辨率影像&#xff0c;具备高精度地形测绘、高精度形变检测、高分辨率宽幅成像以及三维立体成像等能力&#xff0c;在自然资源、应急管理、水利等行业与领域具有极高的…

Spring底层篇

一、什么是Spring&#xff1f;谈谈你对IOC和AOP的理解。 Spring&#xff1a; 是一个企业级java应用框架&#xff0c;他的作用主要是简化软件的开发以及配置过程&#xff0c;简化项目部署环境。 Spring的有点&#xff1a; 1、Spring低侵入设计&#xff0c;对业务代码的污染非…

python游戏开发pygame初步

文章目录 安装和示例移动物体优化 安装和示例 顾名思义&#xff0c;PyGame就是用来做游戏的Python库&#xff0c;提供了许多游戏开发功能&#xff0c;如图像处理、音频播放、事件处理、碰撞检测等等。从这个角度来说&#xff0c;pygame不仅是一个游戏库&#xff0c;同时也是一…

卷积,是什么?

其实就是对事物的作用&#xff0c;或者说作用力&#xff0c;比如说&#xff0c;石板上没有字&#xff0c;我们刻上字&#xff0c;便于识别&#xff0c;从机器视觉角度来说&#xff0c;就是对图像的作用力&#xff0c;这种作用使得能看清想要的东西&#xff0c;感觉还是很主观&a…

Redis面试题:redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)

目录 强一致性&#xff1a;延迟双删&#xff0c;读写锁。 弱一致性&#xff1a;使用MQ或者canal实现异步通知 面试官&#xff1a;redis做为缓存&#xff0c;mysql的数据如何与redis进行同步呢&#xff1f;&#xff08;双写一致性&#xff09; 候选人&#xff1a;嗯&#xff…

为什么淘宝取消双12活动?

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 淘宝取消双12活动了&#xff0c;这条消息犹如一颗重磅炸弹&#xff0c;在整个电商圈中引发了轩然大波。 不过呢&#xff0c;淘宝为了过度&#xff0c;把双12改了个名字叫“好价节”。估计是官方都…

使用skforecast进行时间序列预测

时间序列预测是数据科学和商业分析中基于历史数据预测未来价值的一项重要技术。它有着广泛的应用&#xff0c;从需求规划、销售预测到计量经济分析。由于Python的多功能性和专业库的可用性&#xff0c;它已经成为一种流行的预测编程语言。其中一个为时间序列预测任务量身定制的…

栈详解(C语言)

文章目录 写在前面1 栈的定义2 栈的初始化3 数据入栈4 数据出栈5 获取栈顶元素6 获取栈元素个数7 判断栈是否为空8 栈的销毁 写在前面 本片文章详细介绍了另外两种存储逻辑关系为 “一对一” 的数据结构——栈和队列中的栈&#xff0c;并使用C语言实现了数组栈。 栈C语言实现源…

Vue3中Composition API介绍

在Vue 3中&#xff0c;引入了Composition API&#xff0c;它是一种新的组合式函数API&#xff0c;用于更灵活地组织和重用组件逻辑。Composition API相比于Vue 2中的Options API&#xff0c;提供了更好的可组合性和代码复用性。下面是对Vue 3中Composition API的介绍和用法&…

【自主探索】基于 rrt_exploration 的单个机器人自主探索建图

文章目录 一、rrt_exploration 介绍1、原理2、主要思想3、拟解决的问题4、优缺点 二、安装环境三、安装与运行1、安装2、运行 四、配置说明1、Robots Network2、Robots frame names in tf3、Robots node and topic names4、Setting up the navigation stack on the robots5、A …

【数据库】执行计划中二元操作对一趟扫描算法的应用,理解代价评估的应用和优化,除了磁盘代价还有CPU计算代价不容忽略

二元操作的一趟算法 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏会定…

C#,《小白学程序》第十九课:随机数(Random)第六,随机生成任意长度的大数(BigInteger)

1 文本格式 using System; using System.Linq; using System.Text; using System.Collections.Generic; /// <summary> /// 大数的&#xff08;加减乘除&#xff09;四则运算、阶乘运算 /// 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法 /// 除法运算为 Truffer…

车载以太网-ICMP

文章目录 ICMP协议ICMP报文格式ICMP报文的示例ICMP协议流程ICMP协议报文示例车载以太网ICMP协议测试内容ICMP协议 车载以太网(Ethernet)是一种用于在车辆内部传输数据的网络协议。Internet控制消息协议(ICMP)是一种用于在IP网络上发送错误消息和操作消息的协议。在车载以太…

Leetcode—167.两数之和 II - 输入有序数组【中等】

2023每日刷题&#xff08;四十一&#xff09; Leetcode—167.两数之和 II - 输入有序数组 实现代码 /*** Note: The returned array must be malloced, assume caller calls free().*/ int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {*returnSiz…

Java多线程-面试题+答案——第6期

当准备Java多线程面试时&#xff0c;更多的问题可能涉及到线程池、并发集合、并发工具、锁、原子操作等更深层次的概念。 Java中的CountDownLatch和CyclicBarrier的区别&#xff1a; 答案&#xff1a; CountDownLatch用于等待多个线程完成某个任务&#xff0c;计数器递减到零…

小程序中的大道理之四--单元测试

在讨论领域模型之前, 先继续说下关于测试方面的内容, 前面为了集中讨论相应主题而对此作了推迟, 下面先补上关于测试方面的. 测试覆盖(Coverage) 先回到之前的一些步骤上, 假设我们现在写好了 getPattern 方法, 而 getLineContent 还处于 TODO 状态, 如下: public String ge…

网络视频播放卡顿原因分析

一、问题描述 某项目通过拉摄像机rtsp流转rtmp/http-flv/ws-flv的方案&#xff0c;使用户可以在网页中观看摄像机的视频画面。在 观看视频时偶发出现卡顿现象。 二、卡顿现象分析和解决 此问题涉及的原因较多&#xff0c;所以得考虑各环节的问题可能性&#xff0c;并根据现场实…

Apache多后缀解析漏洞分析

漏洞介绍 该漏洞与用户的配置有密切的关系,严格来说属于用户配置问题。Apache文件解析漏洞涉及到 Apache 解析文件的特性。在默认情况下,Apache 允许一个文件具有多个以点分割的后缀,在处理文件时会从右向左识别后缀名。(就是右边的后缀名无法识别,则继续识别左边的) 如果…

C#与C++进行字段内存对齐

通过预留字段来补齐内存分配。在实际项目中采用这种方法较多&#xff0c;即保证了长度一致&#xff0c;也为以后的扩展提供了容错的可能性。 unsafe struct StructSequential{public fixed float x[8];public fixed float y[8];public fixed float z[8];public fixed float ti…