Что заставляет Iterable.map работать с функциями приостановки? - PullRequest
5 голосов
/ 21 июня 2019

Как правило, suspend fun s нельзя использовать вместо обычных fun s. Если вы попытаетесь вызвать suspend fun напрямую с обычного fun, вы получите ошибку во время компиляции.

В этом блоге упоминается, что вы можете создать параллельную карту в Котлине, написав

list.map { async { f(it) } }.map { it.await() }

Почему второй map компилируется? Обычно вы не можете передать suspend fun вместо fun. Это

  • что map является inline fun и что подвеска автоматически выводится "вверх по течению"
  • , что map является каким-то особенным случаем Котлина
  • что-то еще?

1 Ответ

4 голосов
/ 21 июня 2019

эта карта - забавная игра, и приостановка автоматически выводится "вверх по течению"

Да. Приостановка веселья проверяется после встраивания. Я не вижу явного упоминания об этом в документации, но есть одно в Coroutines KEEP :

Примечание. Приостановочные лямбды могут вызывать приостанавливающие функции во всех местах их кода, где разрешен нелокальный оператор возврата из этой лямбды. То есть приостановка вызовов функций внутри встроенных лямбда-выражений, таких как блок apply {}, разрешена, но не в noinline и не в перекрестных внутренних лямбда-выражениях . Суспензия рассматривается как особый вид нелокальной передачи управления.

...