【Rust自学】13.6. 迭代器 Pt.2:消耗和产生迭代器的方法

13.6.0. 写在正文之前

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

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

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

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

13.6.1. 消耗迭代器的方法

在标准库中,Iterator trait有一些带默认实现的方法。其中有一些会调用next方法,所以说想实现Iterator trait就必须实现next方法。

调用next方法的方法叫做"消耗性适配器 ",因为next方法会把迭代器内的元素一个一个消耗掉,最终会把迭代器耗尽。

举个例子,sum方法会获取迭代器的所有权,并通过重复调用next来迭代项目,从而消耗迭代器。在迭代时,它将每个项目添加到运行总和中,并在迭代完成时返回总和。

rust 复制代码
#[cfg(test)]
mod tests {
    #[test]
    fn iterator_sum() {
        let v1 = vec![1, 2, 3];
        let v1_iter = v1.iter();
        let total: i32 = v1_iter.sum();
        assert_eq!(total, 6);
    }
}

13.6.2. 产生其它迭代器的方法

Iterator trait上还定义了其它方法,叫做"迭代器适配器"。它们会把当前的迭代器转换为不同种类的迭代器。而且你可以通过链式调用多个迭代器适配器来执行复杂的操作,这种调用可读性较高。

map方法为例,它接收一个闭包,闭包作用于迭代器的每个元素。它把当前迭代器的每个元素给转换为另外一个元素,然后这些另外的元素就组成了一个新的迭代器。

rust 复制代码
let v1: Vec<i32> = vec![1, 2, 3];
v1.iter().map(|x| x + 1);

这段代码会对Vector内的每个元素执行加1的操作。

这么写本身没有问题,但是编译器会产生警告:

$ cargo run
   Compiling iterators v0.1.0 (file:///projects/iterators)
warning: unused `Map` that must be used
 --> src/main.rs:4:5
  |
4 |     v1.iter().map(|x| x + 1);
  |     ^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: iterators are lazy and do nothing unless consumed
  = note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
  |
4 |     let _ = v1.iter().map(|x| x + 1);
  |     +++++++

warning: `iterators` (bin "iterators") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.47s
     Running `target/debug/iterators`

由于Rust的迭代器是惰性的,如果你没有消耗它们(指你不调用那些消耗性适配器方法 ),那么它们就什么都不会做。也就是说现在这个状态它并不会对Vector里的三个元素进行加1的操作,除非调用一些消耗性的方法:

rust 复制代码
let v1: Vec<i32> = vec![1, 2, 3];
let v2:Vec<_> = v1.iter().map(|x| x + 1).collect();

这里使用了collect这个消耗性的适配器方法,把结果收集到某个类型的集合里。由于可以collect可以转很多集合类型,所以这里得显式声明v2的类型是Vector,也就是写Vec<_>Vec<_>_代表让编译器自行推断元素的类型。

相关推荐
雷神乐乐7 分钟前
Java操作Excel导入导出——POI、Hutool、EasyExcel
java·开发语言·spring boot·poi·easyexcel·hutool
m0_7482365834 分钟前
解决Spring Boot中Druid连接池“discard long time none received connection“警告
spring boot·后端·oracle
Q_274378510936 分钟前
基于Spring Boot的车间调度管理系统
java·spring boot·后端
凉冰不加冰1 小时前
JVM直击重点
开发语言·jvm
miilue1 小时前
[LeetCode] 链表I — 704#设计链表 | 203#移除链表元素 | 206#反转链表 | 递归法
java·开发语言·c++·算法·leetcode·链表
Pandaconda2 小时前
【新人系列】Python 入门(二十七):Python 库
开发语言·笔记·后端·python·面试··python库
青灯文案12 小时前
Spring 中的 BeanFactory 和 ApplicationContext 详解
java·后端·spring
0xCC说逆向2 小时前
Windows图形界面(GUI)-QT-C/C++ - Qt键盘与鼠标事件处理详解
c语言·开发语言·c++·windows·qt·win32·1024程序员节
索然无味io2 小时前
PHP基础--流程控制
前端·笔记·后端·学习·web安全·网络安全·php
Pandaconda2 小时前
【Golang 面试题】每日 3 题(三十六)
开发语言·经验分享·笔记·后端·面试·golang·go