《Rust编程入门》8.2 迭代器与迭代器适配器
8.2 迭代器与迭代器适配器
在 Rust 中,迭代器是一个非常强大的特性,它允许你以一致的方式访问集合中的元素。Rust 的迭代器是懒惰的,这意味着它们不会立即执行,而是会在需要时按需计算。这使得迭代器非常高效,特别是在处理大型集合时。
8.2.1 迭代器基础
迭代器是实现了 Iterator
特征的类型。Iterator
特征提供了一个核心方法 next()
,它返回一个 Option<T>
,每次调用都会返回集合中的下一个元素,直到没有元素可供迭代。
创建一个简单的迭代器
|
|
v.iter()
返回一个迭代器,它可以遍历Vec
中的元素。next()
每次调用返回一个Option
类型,如果迭代器中还有元素,next()
会返回Some(value)
;如果没有元素,则返回None
。
使用 for
循环简化迭代
|
|
- 在 Rust 中,
for
循环可以自动处理迭代器,省去了手动调用next()
的麻烦。
消费者方法:sum()
Rust 提供了一些常用的迭代器方法,可以对集合进行操作并返回最终结果。sum()
是其中之一,它可以对迭代器中的所有元素进行求和。
|
|
sum()
通过迭代器计算集合中元素的总和。
8.2.2 迭代器适配器
迭代器适配器是链式方法,可以对迭代器执行转换、过滤和其他操作。迭代器适配器本身并不立即执行,而是返回一个新的迭代器,只有在实际遍历时,所有操作才会生效。
map
适配器
map
适配器可以将一个闭包应用到每个元素上,生成新的元素。例如,可以对每个数字进行平方操作:
|
|
map
返回一个新的迭代器,其中每个元素都经过闭包的处理。collect()
方法用于将迭代器的结果收集到一个集合中(此例中是Vec<i32>
)。
filter
适配器
filter
适配器根据给定的条件过滤元素。例如,只保留偶数:
|
|
filter
接受一个闭包,只有返回true
的元素会被保留。- 这里的闭包
|&&x| x % 2 == 0
用于筛选偶数。
take
和 skip
适配器
take
适配器会从迭代器中返回前n
个元素。skip
适配器会跳过迭代器中的前n
个元素,返回剩余部分。
|
|
take(3)
选择前 3 个元素。skip(2)
跳过前 2 个元素,返回剩余部分。
fold
适配器
fold
适配器是一个非常强大的方法,它允许你对迭代器中的元素进行累计操作,返回一个最终结果。与 reduce
类似,它从初始值开始,逐步应用闭包中的操作。
|
|
fold(0, |acc, &x| acc + x)
从0
开始,累加每个元素的值。
zip
适配器
zip
适配器用于将两个迭代器“压缩”成一个新的迭代器,其中每个元素是一个元组,包含两个原始迭代器的元素。
|
|
zip
将两个迭代器中的元素配对成元组。
8.2.3 迭代器的惰性计算
Rust 中的迭代器是惰性(lazy)的,意味着它们不会立即执行。只有当我们真正遍历它们时,才会进行计算。通过这种方式,Rust 能够避免不必要的计算,提高性能。
例如,下面的代码展示了 map
和 filter
适配器的惰性特性:
|
|
- 在执行时,
map
和filter
会依次处理元素,但没有立即产生结果,直到调用collect()
才会进行所有的计算。
8.2.4 小结
- 迭代器是 Rust 中的核心特性,它允许以一致的方式访问集合中的元素,并提供了多种常用操作。
- Rust 的迭代器是惰性求值的,只有在实际遍历时才会执行计算,这有助于提高性能。
- 迭代器适配器(如
map
、filter
、fold
等)可以对迭代器进行转换,返回一个新的迭代器,使得处理数据的方式更加灵活。
在下一节中,我们将深入探讨闭包与高阶函数,它们与迭代器和迭代器适配器紧密结合,进一步提升 Rust 的表达力和灵活性。