TL; DR: используйте suspend { ... } для создания приостанавливающей лямбды. Это все.

При первой работе с сопрограммами Kotlin вы быстро столкнетесь с ключевым словом suspend как средством пометки функции как «приостанавливающей функции». Например:

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

Это расширение позволяет преобразовать типичную функцию приостановки в Flow. В этом случае ключевое слово suspend используется для описания приостановленного функционального типа:

Это интуитивно имеет некоторый смысл: так же, как есть способ определить не приостанавливающие функциональные типы, такие как () -> T, должен быть способ определить приостанавливающие. Пример, приведенный в документации для функции выше, предоставляет один из способов получить ссылку на функцию такого типа. Учитывая функцию приостановки без аргументов, например

Затем функция типа suspend () -> R может быть возвращена через ссылку на функцию ::remoteCall. Это просто приостанавливающий эквивалент дела без приостановки. Например, учитывая

ссылка на функцию ::nonSuspendingCall будет иметь тип () -> R.

Однако возникает вопрос: как определить такой функциональный тип с помощью лямбда? Рассмотрим следующую функцию приостановки:

Ссылка на функцию ::downloadFile имеет тип suspend (String) -> File и, например, не подходит для использования с asFlow помощником. У вас может возникнуть соблазн попробовать использовать вспомогательный метод, определив лямбда следующим образом:

Однако это не компилируется при вызове вне функции приостановки и приводит к сообщению об ошибке:

Функция приостановки «downloadFile» должна вызываться только из сопрограммы или другой функции приостановки.

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

Это действительно работает, но это также не совсем удовлетворительно: как разработчики Kotlin мы избалованы выводом типа и чувствуем себя вправе, что он должен существовать и для этого случая. К счастью, есть способ дать нам желаемый результат с другим очень интересным использованием ключевого слова suspend, в котором оно добавляется к определению лямбда:

Синтаксис suspend { … } приводит к «приостановке лямбды» и дает функцию типа suspend () -> T, что и является именно тем, что мы ищем. С помощью этого синтаксиса приостанавливающие лямбда-выражения могут занять их место вместе с их не приостанавливающими братьями и сестрами в качестве еще одного ценного инструмента в наборе инструментов наших сопрограмм (и Kotlin).

Брайан пишет о приостановке ……………… лямбд в Livefront.