昨天我们学了闭包
今天我们往下学Iterator
迭代器相信大家之前有接触过。
在rust
中,迭代器是lazy
的,也就是惰性的。在你把这个迭代器消耗(consume
)完之前,它是不会做任何影响的。
比如:
调用集合类型都有的iter
方法创建一个迭代器。这个是完全没有影响的。
然后我们来用个for
遍历他
这个时候,每当超过当前item
作用域之后这个iterator
就会被消耗一层,然后再进入下一层item
。
iterator trait
和next
方法所有的迭代器都实现了标准库里一个叫Iterator
的trait
。 大概张这个样子,由于截图太长了,没法放进来
这里有一个我们并不认识的语法type Item
,实际上是后面会学到的associate type
也就是关联类型。
它要求我们在impl
这个Iterator
的时候也需要定义一个自己的Item
类型。它会被用在next
这个方法中,以Some(Item)
的方式返回。
另外Iterator
这个trait
只需要我们在实现的时候把next
这个方法实现即可。 这个next
的方法会在每一次迭代的时候返回一个Some(Item)
,然后在迭代结束的时候返回None
。
我们可以直接对迭代器的实例使用next
这个方法,比如
需要注意的一点是迭代器得是mut
的。
iter
这个method
返回的是不可变的借用,如果想要获得所有权,可以调用into_iter
,会返回不可变的所有权,如果想要可变的可以调用into_mut
。
consume
)迭代器的method
Iterator
有一堆api
是用来消耗迭代器的,其中最经典的自然就是next
这个method
。
rust
团队管这种method
叫做*consuming adaptors
,*也就是消耗适配器。
每次调用都会消耗一个迭代器。
另外还有一个是sum
,它会获得迭代器的所有权(记住这一点),然后迭代这个迭代器里所有的项通过重复的调用next
方法,把每个项加起来最后返回。
我们来看个例子
produce
)其它迭代器的method
Iterator adaptors
, 也就是迭代器适配器,它们不会消耗迭代器。
相反,它们会返回一个其它的迭代器通过某些方面改动原来的迭代器。
比如map
方法,它相信大家应该不陌生,ES6+
中提供的高级函数(指接收一个function
作为参数)。
rust
中的map
是迭代器的method
,它是一个迭代器适配器,也就是说不会消耗迭代器并且最终会返回一个新的迭代器。
来看下例子
它接受一个闭包作为参数,并且迭代器的项会作为参数传入闭包中。
看了源码应该可以知道并不会立即执行闭包,而是得等新的迭代器被使用的时候才会执行。
也就是前面说的:lazy
,只有在调用消耗适配器的时候才会执行。
我们可以直接调用collect
方法把这个迭代器转换为一个集合,这也是一种consume
。
然后我们还可以链式调用,比如map(xxx).filter(....).collect
,因为迭代器适配器最终都是返回一个迭代器,所以不用担心链会断掉。 最后再用消耗适配器来消耗掉迭代器即可。
迭代器还是比较简单的,不过大多数时候迭代器是和闭包一起使用的,我们这里涉及不多. 不过前路漫漫,早晚遇到.
发布于 2022-12-28 11:58・IP 属地广东