序列作用域
小于 1 分钟
使用协程时,需要定义一个左右,在该作用域内的协程或挂起函数将起作用。SequenceScope
也是因此被定义,用于使用挂起函数或协程生成序列或迭代器的值。
查看下源码可以加深理解:
public abstract class SequenceScope<in T> internal constructor() {
public abstract suspend fun yield(value: T)
public abstract suspend fun yieldAll(iterator: Iterator<T>)
public suspend fun yieldAll(elements: Iterable<T>) {
if (elements is Collection && elements.isEmpty()) return
return yieldAll(elements.iterator())
}
public suspend fun yieldAll(sequence: Sequence<T>) = yieldAll(sequence.iterator())
}
因此 SequenceScope
提供了 yield
和 yieldAll
挂起函数。
下一个问题是,这一切是如何在序列中联系起来的?
事实证明,前面使用的 sequence {}
语法将 SequenceScope
作为唯一的参数传递给它。
public fun <T> sequence(@BuilderInference block: suspend SequenceScope<T>.() -> Unit): Sequence<T> = Sequence { iterator(block) }
由于 Kotlin 允许转换具有单个参数的函数,用 lambda 表达式代替单个参数,因此你所使用的是提供 SequenceScope
的 sequence {}
DSL。
反过来,当使用 sequence {}
时 ,lambda 体已准备好处理挂起函数,从而能够使用 yield
和 yieldAll
挂起函数。