【问题标题】:How to build a sequence from an external non-suspending function如何从外部非挂起函数构建序列
【发布时间】:2018-01-18 18:43:17
【问题描述】:

我有一个 java 方法 visitChildrenRecursively(Node root, NodeVisitor p),它允许我通过提供 SAM 访问者来迭代树状结构的元素。

我想将此方法转换为基于序列的迭代。

但是,这段代码...

buildSequence {
    visitChildrenRecursively(root, NodeVisitor {
        yield(it)
    })
}

...编译失败,在yield(it) 行出现错误Suspension functions can be called only within coroutine body

Kotlin 协程 Informal description 建议我的 visitChildrenRecursively 可以通过将其包装在 suspendCoroutine 块中来转换为挂起函数。

这是否是正确的方法,或者这甚至可能在不诉诸kotlinxproduce 方法的情况下,如the kotlinx coroutines guide 所示?

我还尝试了非正式描述中的“异步序列”部分,但没有成功。

【问题讨论】:

    标签: kotlin kotlin-coroutines


    【解决方案1】:

    恐怕你在要求不可能的事。 Kotlin 并没有通过一些后门 JVM 魔术来实现协程,而是通过常规 J​​ava 方法的转换。可挂起的函数涉及隐藏的方法签名更改及其返回类型的更改。你的Visitor 可能有一个方法

    void visit(Node)
    

    这必须变成

    Object visit(Node, Continuation)
    

    即使我们假装这是可能的,你的下一个障碍将是visitChildrenRecursively(),它不知道可暂停函数的特殊合约。它们要求调用者将其延续传递给正常调用,而他们自己的延续传递给恢复调用。他们在挂起时返回COROUTINE_SUSPENDED,如果调用者得到它,它必须自己返回相同的值。

    如果您可以复制粘贴visitChildrenRecursively() 的实现并将其迁移到Kotlin,那么您可能会有成功的机会。

    【讨论】:

      猜你喜欢
      • 2020-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      • 2016-10-29
      • 2020-01-27
      相关资源
      最近更新 更多