如何从外部非挂起函数构建序列

时间:2018-01-18 18:43:17

标签: kotlin kotlin-coroutines

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

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

然而,这段代码......

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

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

Kotlin协程Informal description表明我的visitChildrenRecursively可以通过将其suspendCoroutine块包装在其中来转换为暂停功能。

这是正确的做法,或者如果不采用来自produce kotlinx的{​​{1}}方法,这是否可行,如the kotlinx coroutines guide所示?

我也试过了#34;异步序列"在非正式的描述中,没有运气。

1 个答案:

答案 0 :(得分:2)

我担心你会要求不可能的事情。 Kotlin没有通过一些后门JVM魔法实现协同程序,而是通过常规Java方法的转换。可挂起的函数涉及隐藏的方法签名更改以及它们的返回类型更改。您Visitor可能有方法的地方

void visit(Node)

这必须成为

Object visit(Node, Continuation)

即使我们假装这是可能的,你的下一个障碍是visitChildrenRecursively(),它不知道可暂停功能的特殊合同。它们要求呼叫者传递其继续进行正常呼叫以及他们自己的继续进行恢复呼叫。它们在挂起时返回COROUTINE_SUSPENDED,并且调用者必须返回相同的值才能获得它。

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