我正在学习Kotlin的协程。
代码A来自https://kotlinlang.org/docs/reference/coroutines/flow.html的文字
yield(i)
在科特林语中是什么意思?
代码A
fun foo(): Sequence<Int> = sequence { // sequence builder
for (i in 1..3) {
Thread.sleep(100) // pretend we are computing it
yield(i) // yield next value
}
}
fun main() {
foo().forEach { value -> println(value) }
}
答案 0 :(得分:2)
这不是协程功能。此代码是与协程流进行比较的示例。序列是用于延迟评估每个元素的迭代器。列表包含所有提前的值,但是序列仅在诸如forEach
调用(“终端”序列函数)之类的请求时才计算每个值。
上面的代码只是模拟一个十分之一秒的序列来计算其每个值。它只是产生数字1、2和3。yield()
是如何告诉sequence
构建器函数产生另一个要使用的值的。
通过sequence
构建器函数,您可以传递一个lambda,该lambda一次计算一个值,然后通过调用yield()
返回它们。
更常见的是不使用构建器,而是使用toSequence()
将某些集合转换为Sequence,然后可以在Sequence上链接类似map
的操作,直到对它们进行评估像forEach
这样的终端操作被调用。这样可以避免为每个操作分配中间列表。
答案 1 :(得分:0)
在sequence
中调用yield(something)
表示iterator of the Sequence
hasNext()
,并且在您致电something
时会得到next()
。
迭代器的用户调用next()
然后再次调用hasNext()
之后,将从yield
恢复执行。
当只产生1 2 3时,它看起来毫无意义。但是请考虑进行二叉树遍历。预购,有序或后购都很容易用递归代码编写。我们可以使用调用堆栈来记住下一步该做什么。
当我们想要构建一个迭代器时,我们会失去所有这些好东西。我们必须使用显式堆栈来记住下一个要访问的节点-除非我们使用sequence
函数。
same fringe problem是其强大功能的一个例子。
我不同意另一个回答,即“这不是协程功能”。 能够在执行过程中恢复是 co </ strong>例程的定义。将其与必须从头开始运行的 sub 例程进行对比。
我们经常使用“协程”来指代Kotlin中的并发构造。序列构建不是这些的一部分,而是协程的一个例子。