【问题标题】:What does yield(i) mean in Kotlin?在 Kotlin 中 yield(i) 是什么意思?
【发布时间】:2020-06-28 02:25:17
【问题描述】:

我正在学习 Kotlin 的协程。

代码 A 来自文章https://kotlinlang.org/docs/reference/coroutines/flow.html

yield(i) 在 Kotlin 中是什么意思?

代码 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) } 
}

【问题讨论】:

  • 如果你知道任何 Python,yield(i) 与 Python 生成器函数的 yield i 非常相似。但在 Kotlin 中,它不是语言功能,它只是 suspend fun

标签: kotlin kotlin-coroutines


【解决方案1】:

这不是协程功能。此代码是与协程流进行比较的示例。序列是惰性计算每个元素的迭代器。列表提前包含所有值,但序列仅在 forEach 调用(“终端”序列函数)等请求时计算每个值。

上面的代码只是模拟一个需要十分之一秒来计算每个值的序列。它只是生成数字 1、2 和 3。yield() 是告诉 sequence 构建器函数生成另一个要使用的值的方式。

sequence 构建器函数允许您传递一个 lambda,它一次计算一个值并通过调用 yield() 返回它们。

更常见的是不使用构建器,而是将一些集合转换为带有toSequence() 的序列,然后您可以在序列上链接map 之类的操作,直到像@ 之类的终端操作才会评估它们987654328@ 被调用。这样做的好处是避免为每个操作分配中间列表。

【讨论】:

    【解决方案2】:

    sequence 中调用yield(something) 表示iterator of the Sequence hasNext(),当你调用next() 时你会得到something

    迭代器的用户调用next(),然后再次调用hasNext()后,将从yield继续执行。


    当它只产生 1 2 3 时看起来毫无意义。但考虑进行二叉树遍历。 Pre-order、in-order 或 post-order 都非常容易用递归代码编写。我们可以使用调用堆栈来记住下一步该做什么。

    当我们想要构建一个迭代器时,我们失去了所有的好东西。我们必须使用显式堆栈来记住接下来要访问的节点 - 除非我们使用 sequence 函数。

    same fringe problem 就是一个例子。


    我不同意另一个答案,即“这不是协程功能”。 能够在执行中间恢复是co例程的定义。将其与必须从一开始就运行的例程进行对比。

    我们经常使用“协程”来指代 Kotlin 中的并发构造。序列构建不是其中的一部分,但仍然是协程的一个示例。

    【讨论】:

      猜你喜欢
      • 2017-11-09
      • 1970-01-01
      • 2019-06-25
      • 2015-09-18
      • 2020-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多