Estoy confundido acerca de lo que está pasando con el siguiente código. task.yield es un hashmap de a a b, y store.put es una función de suspensión que toma una a y una b. La primera forma de iterar a través del mapa funciona sin problemas, al igual que la segunda. La tercera forma, que me parece la forma más natural de hacer la iteración y fue lo que escribí inicialmente, hace que Kotlin se queje de que las funciones de suspensión solo se pueden llamar dentro de un cuerpo coroutine. Supongo que esto tiene que ver con cómo funciona forEaching en un mapa (¿a diferencia de una lista, tal vez?), Pero realmente no entiendo cuál es el problema.
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) } }Editar: acabo de darme cuenta de que la lista para cada uno es una función en línea, mientras que el mapa que estoy tratando de usar no lo es. Supongo que este es el problema.
De hecho, la sobrecarga de Map#forEach que acepta una (K, V) -> Unit (un BiConsumer<? super K, ? super V> ) no forma parte de las bibliotecas estándar de Kotlin sino del propio JDK ( Map#forEach ). Esto explica por qué cualquier cosa que se ejecute dentro de este bloque no está en línea y, por lo tanto, no forma parte del "contexto de suspensión" adjunto.
Hay una función muy similar que proporciona Kotlin que puede utilizar:
inline fun <K, V> Map<out K, V>.forEach(action: (Entry<K, V>) -> Unit)Realiza la acción dada en cada entrada.
kotlin-stdlib / kotlin.colecciones / forEach
Esto acepta una Entry<K, V> , por lo que simplemente puede desestructurarla dentro de la lambda:
task.yield.forEach { (t, u) /* <-- this */ -> store.put(t, u) }