【Rust自学】13.8. 迭代器 Pt.4:创建自定义迭代器

13.8.0. 写在正文之前

Rust语言在设计过程中收到了很多语言的启发,而函数式编程对Rust产生了非常显著的影响。函数式编程通常包括通过将函数作为值传递给参数、从其他函数返回它们、将它们分配给变量以供以后执行等等。

在本章中,我们会讨论 Rust 的一些特性,这些特性与许多语言中通常称为函数式的特性相似:

  • 闭包
  • 迭代器(本文)
  • 使用闭包和迭代器改进I/O项目
  • 闭包和迭代器的性能

喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

13.8.1. 使用Iterator trait创建自定义迭代器

最主要的步骤就只有一步:提供next方法的实现。

看个例子:

做一个迭代器,从1遍历到5

rust 复制代码
struct Counter {  
    count: u32,  
}  
  
impl Counter {  
    fn new() -> Counter {  
        Counter { count: 0 }  
    }  
}  
  
impl Iterator for Counter {  
    type Item = u32;  
    fn next(&mut self) -> Option<u32> {  
        if self.count < 5 {  
            self.count += 1;  
            Some(self.count)  
        } else {  
            None  
        }  
    }  
}
  • 先创建一个结构体叫Counter,它有count字段,用来存储迭代过程中所需要的数值,也就是迭代过程中的状态。这里count字段不使用pub而是设为私有是为了让Counter结构体独立管理它的值。

  • 然后在这个结构体上写了一个关联函数new用于创建新的实例,确保新实例从0开始。

  • 下面就需要为Counter这个结构体实现Iterator这个trait。Iterator trait有一个关联类型type Item还有一个next方法。首先把关联类型指定为u32,也就是写type Item = u32;。这个语法在第19章会细讲,现在知道这个迭代器会返回u32类型即可。

  • next函数的返回类型是Option<Self::Item>,由于上文写了关联类型指定为u32,所以可以理解为Option<u32>。当count字段小于5的时候就继续加1,如果大于等于5就返回None。这样就能保证从1到5的遍历。

现在我们来实现复杂一些的需求:

一样是Counter结构体,一个是从1到5,另一个是从2到5,把两个这样的迭代器的每对元素相乘,产生的新迭代器里的元素要求必须能被3整除,然后把这些元素的和返回

rust 复制代码
fn using_other_iterator_traits_methods() {  
    let sum: u32 = Counter::new()  
        .zip(Counter::new().skip(1))  
        .map(|(a, b)| a * b)  
        .filter({|x| x % 3 == 0})  
        .sum();  
}
  • 这里我分行写是因为链式调用写在一行太长了,如果链式调用的代码没多长就没必要分行写
  • zip方法是把两个迭代器的每对元素和到一起形成新迭代器,这个新迭代器的元素就是元组,每个元组有两个值,分别来自两个迭代器。
  • Counter::new()就是建立一个从1到5的Counter结构体,Counter::new().skip(1)就是建立跳过1的Counter结构体,也就是从2到5。把这两个结构体实例使用zip和到一起就会形成如下表格的存储元组(Tuple)的迭代器:
Counter::new() Counter::new().skip(1)
Tuple 0 1 2
Tuple 1 2 3
Tuple 2 3 4
Tuple 3 4 5
PS:Counter::new()不会遍历到5是因为Counter::new().skip(1)在那时的值是None,程序就不会再生成值
  • map接收一个闭包,闭包作用于迭代器的每个元素。它把当前迭代器的每个元素给转换为另外一个元素,然后这些另外的元素就组成了一个新的迭代器。在这个例子中就是把迭代器存储的元组里的两个值相乘得到新的迭代器。
  • filter通过闭包把能整除3的值留下形成新的迭代器
  • sum消耗迭代器的所有元素,把其中的所有值相加求和

最后的结果应该是18

相关推荐
neoooo2 分钟前
别慌,Java只有值传递——一次搞懂“为啥我改了它还不变”!
java·后端·spring
wuxuanok5 分钟前
Web后端开发-请求响应
java·开发语言·笔记·学习
用户7785371836966 分钟前
一力破万法:从0实现一个http代理池
后端·爬虫
Sally璐璐24 分钟前
IPSAN 共享存储详解:架构、优化与落地实践指南
开发语言·php
拖孩32 分钟前
微信群太多,管理麻烦?那试试接入AI助手吧~
前端·后端·微信
像风一样的男人@35 分钟前
python --货车装厢问题
开发语言·python
Humbunklung42 分钟前
Rust枚举:让数据类型告别单调乏味
开发语言·后端·rust
Y1nhl1 小时前
力扣_链表_python版本
开发语言·python·算法·leetcode·链表·职场和发展
radient1 小时前
Golang-GMP 万字洗髓经
后端·架构
蓝倾1 小时前
如何使用API接口实现淘宝商品上下架监控?
前端·后端·api