【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<_>_代表让编译器自行推断元素的类型。

相关推荐
程序喵大人9 分钟前
【C++进阶】STL容器与迭代器 - 01 STL 容器先解决元素放在哪里
开发语言·c++·stl
doiito23 分钟前
【Agent Harness】Gliding Horse 高级认知优化:让 Agent 的“大脑”和“免疫系统”真正协同
ai·rust·架构设计·系统设计·ai agent
cui_ruicheng26 分钟前
Python从入门到实战(十六):多进程编程
开发语言·python
腾讯云云开发1 小时前
腾讯云 CloudBase 登上 WAIC:我们为 Agent 重新设计了云的生产线
后端
星栈1 小时前
从装一堆工具到看懂 Node 工程化思维:我的项目复盘记录
后端·node.js
65岁退休Coder2 小时前
LangChain v1.3.4 笔记 - 05 Agent 上下文记忆
后端
颜酱2 小时前
04 | 召回前置准备:搭好召回所需的四个数据库
前端·人工智能·后端
wdfk_prog2 小时前
嵌入式面试真题第 15 题:不可恢复异常后的通用崩溃快照、调用栈保存与离线分析架构
linux·开发语言·面试·架构
JaneConan2 小时前
鸿蒙 韶非 UI 系列:能力调用 startAbilityForResult,跳能力拿回参,鸿蒙能力路由入门
后端·harmonyos
晴空了无痕2 小时前
从 Go 基础到 K8s:一条可落地的 Go 服务端成长路线
开发语言·后端·golang·kubernetes