我对以下代码发生了什么感到困惑。 task.yield是从a到b的哈希表,而store.put是一个使用a和b的暂停函数。遍历地图的第一种方法没有问题,第二种方法也没有问题。第三种方式对我来说是最自然的迭代方式,也是我最初编写的方式,它使Kotlin抱怨只能在协程体内调用暂停功能。 我猜想这与地图上的forEach的工作方式有关(也许与列表相对吗?),但我并不真正了解问题所在。
launch{
// Kotlin is perfectly happy with this
for(elt in task.yield.keys){
store.put(elt,task.yield[elt]!!)
}
// and this
task.yield.keys.forEach {
store.put(it,task.yield[it]!!)
}
// This makes kotlin sad. I'm not sure why
task.yield.forEach { t, u ->
store.put(t, u)
}
}
编辑:我刚刚注意到forEach的列表是一个内联函数,而我尝试使用的地图则不是。我猜这是问题所在。
答案 0 :(得分:3)
实际上,接受Map#forEach
((K, V) -> Unit
)的BiConsumer<? super K, ? super V>
的重载不是Kotlin标准库的一部分,而是JDK本身(Map#forEach
)的一部分。 。这就解释了为什么在此块中执行的任何内容都不会内联,因此不属于封闭的“悬浮上下文”。
Kotlin提供了一个非常相似的功能,您可以使用:
inline fun <K, V> Map<out K, V>.forEach(action: (Entry<K, V>) -> Unit)
对每个条目执行给定的操作。
kotlin-stdlib / kotlin.collections / forEach
这接受Entry<K, V>
,因此您可以在lambda中简单地destructure:
task.yield.forEach { (t, u) /* <-- this */ ->
store.put(t, u)
}