
13.6 迭代器 Pt.2消耗和产生迭代器的方法13.6.0. 写在正文之前Rust语言在设计过程中受到了很多语言的启发而函数式编程对Rust产生了非常显著的影响。函数式编程通常包括通过将函数作为值传递给参数、从其他函数返回它们、将它们分配给变量以供以后执行等等。在本章中我们会讨论 Rust 的一些特性这些特性与许多语言中通常称为函数式的特性相似- 闭包-迭代器本文- 使用闭包和迭代器改进I/O项目- 闭包和迭代器的性能13.6.1. 消耗迭代器的方法在标准库中Iteratortrait有一些带默认实现的方法。其中有一些会调用next方法所以说想实现Iteratortrait就必须实现next方法。调用next方法的方法叫做“消耗性适配器”因为next方法会把迭代器内的元素一个一个消耗掉最终会把迭代器耗尽。举个例子sum方法会获取迭代器的所有权并通过重复调用next来迭代项目从而消耗迭代器。在迭代时它将每个项目添加到运行总和中并在迭代完成时返回总和。#[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. 产生其它迭代器的方法在Iteratortrait上还定义了其它方法叫做“迭代器适配器”。它们会把当前的迭代器转换为不同种类的迭代器。而且你可以通过链式调用多个迭代器适配器来执行复杂的操作这种调用可读性较高。以map方法为例它接收一个闭包闭包作用于迭代器的每个元素。它把当前迭代器的每个元素给转换为另外一个元素然后这些另外的元素就组成了一个新的迭代器。let v1: Veci32 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)] (part of #[warn(unused)]) 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.06s Running target/debug/iterators由于Rust的迭代器是惰性的如果你没有消耗它们指你不调用那些消耗性适配器方法那么它们就什么都不会做。也就是说现在这个状态它并不会对Vector里的三个元素进行加1的操作除非调用一些消耗性的方法let v1: Veci32 vec![1, 2, 3]; let v2:Vec_ v1.iter().map(|x| x 1).collect();这里使用了collect这个消耗性的适配器方法把结果收集到某个类型的集合里。由于可以collect可以转很多集合类型所以这里得显式声明v2的类型是Vector也就是写Vec_。Vec_的_代表让编译器自行推断元素的类型。