参考章节《Rust 程序设计语言》第13.2章 使用迭代器处理元素序列
迭代器是遍历数据的一种方式
迭代器模式允许你对一个序列的项进行某些处理。
迭代器(iterator)负责遍历序列中的每一项和决定序列何时结束的逻辑。当使用迭代器时,我们无需重新实现这些逻辑。
在 Rust 中,迭代器是 惰性的(lazy),这意味着在调用方法使用迭代器之前它都不会有效果。
先看一个例子
- 迭代器的第一种使用方法
|
|
- 迭代器的第二种使用方法
Iterator trait 和 next 方法
迭代器都实现了一个叫做 Iterator
的定义于标准库的 trait
。这个 trait
的定义看起来像这样
|
|
可以直接调用迭代器的 next
方法,获取迭代器中的下一个元素
|
|
注意
v1_iter
需要是可变的
:在迭代器上调用next
方法改变了迭代器中用来记录序列位置的状态。
换句话说,代码消费了
,或使用了迭代器。每一次next
调用都会从迭代器中消费一个项。
你可能注意到上面使用for
循环方式时没有使v1_iter
可变,那是因为for
循环会获取v1_iter
的所有权并在后台使v1_iter
可变。
另外需要注意到从
next
调用中得到的值是vector
的不可变引用。iter
方法生成一个不可变引用的迭代器。
如果我们希望迭代可变引用,则可以调用iter_mut
而不是iter
。
如果我们需要一个获取v1
所有权并返回拥有所有权的迭代器,则可以调用into_iter
而不是iter
。
消费适配器
Iterator trait
有一系列不同的由标准库提供默认实现的方法
一些方法在其内部调用了next
方法,这些调用next
方法的方法被称为消费适配器(consuming adaptors)
,因为调用他们会消耗迭代器。
sum
方法获取迭代器的所有权并反复调用 next
来遍历迭代器,因而会消费迭代器。当其遍历每一个项时,它将每一个项加总到一个总和并在迭代完成时返回总和。
|
|
迭代器适配器
迭代器适配器的特点是会产生一个新的迭代器
Iterator trait
中定义了另一类方法,被称为迭代器适配器(iterator adaptors)
,他们允许我们将当前迭代器变为不同类型的迭代器。
可以链式调用多个迭代器适配器。不过因为所有的迭代器都是惰性的,必须调用一个消费适配器方法以便获取迭代器适配器调用的结果
。
map
方法调用迭代器的 next
方法,并使用闭包来处理每个元素(这里为每个元素 + 1),最后生成新的迭代器。
|
|
书中使用闭包获取环境这一节讲了一个例子,我觉得太啰嗦了,所以没有写,有兴趣可以去看看,也不难,无非是讲 filter
迭代器适配器的用法
自定义迭代器
迭代器定义中唯一要求提供的方法就是
next
方法。一旦定义了它,就可以使用所有其他由Iterator trait
提供的拥有默认实现的方法来创建自定义迭代器了!
让我们创建一个只会从 1
数到 5
的迭代器。首先,创建一个结构体来存放一些值,接着实现 Iterator trait
将这个结构体放入迭代器中并在此实现中使用其值。
|
|
总结一下
- 迭代器可以通过
for
循环和next
方式来使用它 - 消费适配器方法会获取迭代器的
所有权
- 迭代器适配器方法会产生一个
新的迭代器
- 自定义迭代器需要实现
Iterator trait
的next
方法