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

相关推荐
獨枭14 分钟前
使用 163 邮箱实现 Spring Boot 邮箱验证码登录
java·spring boot·后端
维基框架19 分钟前
Spring Boot 封装 MinIO 工具
java·spring boot·后端
秋野酱19 分钟前
基于javaweb的SpringBoot酒店管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
关于不上作者榜就原神启动那件事20 分钟前
Java基础学习
java·开发语言·学习
橙子1991101625 分钟前
在 Kotlin 中,什么是解构,如何使用?
android·开发语言·kotlin
☞无能盖世♛逞何英雄☜32 分钟前
Flask框架搭建
后端·python·flask
Q_Q196328847541 分钟前
python的家教课程管理系统
开发语言·spring boot·python·django·flask·node.js·php
Black_Cat_yyds1 小时前
设计杂谈-工厂模式
java·开发语言
进击的雷神1 小时前
Perl语言深度考查:从文本处理到正则表达式的全面掌握
开发语言·后端·scala
进击的雷神1 小时前
Perl测试起步:从零到精通的完整指南
开发语言·后端·scala