如何从外部非挂起函数构建序列
How to build a sequence from an external non-suspending function
我有一个 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
块中转换为挂起函数。
这是否是正确的方法,或者这是否可能不求助于 kotlinx
中的 produce
方法,如 the kotlinx coroutines guide 所示?
我也尝试了非正式描述中的 "Asynchronous sequences" 部分,但没有成功。
恐怕你要求的是不可能的。 Kotlin 并没有通过一些后门 JVM 魔法来实现协程,而是通过常规 Java 方法的改造。可挂起函数涉及隐藏方法签名更改及其 return 类型更改。你的 Visitor
可能有一个方法
void visit(Node)
这必须变成
Object visit(Node, Continuation)
即使我们假设这是可能的,您的下一个障碍将是 visitChildrenRecursively()
,它不了解可暂停功能的特殊合同。他们要求调用者为正常呼叫传递其延续,为恢复呼叫传递他们自己的延续。它们 return COROUTINE_SUSPENDED
挂起时,调用者必须 return 获得相同的值。
如果您可以复制粘贴 visitChildrenRecursively()
的实现并将其迁移到 Kotlin,那么您可能有机会成功。
我有一个 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
块中转换为挂起函数。
这是否是正确的方法,或者这是否可能不求助于 kotlinx
中的 produce
方法,如 the kotlinx coroutines guide 所示?
我也尝试了非正式描述中的 "Asynchronous sequences" 部分,但没有成功。
恐怕你要求的是不可能的。 Kotlin 并没有通过一些后门 JVM 魔法来实现协程,而是通过常规 Java 方法的改造。可挂起函数涉及隐藏方法签名更改及其 return 类型更改。你的 Visitor
可能有一个方法
void visit(Node)
这必须变成
Object visit(Node, Continuation)
即使我们假设这是可能的,您的下一个障碍将是 visitChildrenRecursively()
,它不了解可暂停功能的特殊合同。他们要求调用者为正常呼叫传递其延续,为恢复呼叫传递他们自己的延续。它们 return COROUTINE_SUSPENDED
挂起时,调用者必须 return 获得相同的值。
如果您可以复制粘贴 visitChildrenRecursively()
的实现并将其迁移到 Kotlin,那么您可能有机会成功。