Котлин foreach на карте против перебора ключей при использовании с сопрограммами - PullRequest
0 голосов
/ 12 января 2019

Я не совсем понимаю, что происходит со следующим кодом. task.yield является хэш-картой от a до b, а store.put является функцией приостановки, которая принимает a и a b. Первый способ итерации по карте работает без проблем, как и второй. Третий способ, который кажется мне наиболее естественным для выполнения итерации и который я написал изначально, заставляет kotlin жаловаться на то, что функции приостановки могут вызываться только внутри тела сопрограммы. Я предполагаю, что это связано с тем, как forEaching на карте работает (в отличие от списка, может быть?), Но я не совсем понимаю, в чем проблема.

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)
    }
}

Edit: я только что заметил, что список forEach является встроенной функцией, а карта, которую я пытаюсь использовать, - нет. Я предполагаю, что это проблема.

1 Ответ

0 голосов
/ 12 января 2019

Действительно, перегрузка 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>, поэтому вы можете просто уничтожить внутри лямбды:

task.yield.forEach { (t, u) /* <-- this */ ->
    store.put(t, u)
}
...