Модификаторы noinline и crossinline
Управляйте встраиванием отдельных параметров-лямбд в inline-функциях.
«Модификаторы noinline и crossinline» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.
Проблема, которую решает встраивание, и новые проблемы
Когда функция является inline, все её параметры-лямбды по умолчанию встраиваются. Иногда нужно, чтобы конкретная лямбда не встраивалась — например, чтобы сохранить её или передать другой невстроенной функции.
Сохранение одной лямбды как объекта
Добавьте noinline перед конкретным параметром-лямбдой, чтобы исключить его из встраивания, оставив остальные параметры встроенными.
inline fun doWork(
action: () -> Unit,
noinline callback: () -> Unit // stored, not inlined
) {
action() // inlined at call site
scheduleCallback(callback) // passed as object — valid
}Когда необходимо отключить встраивание лямбды
Используйте noinline, когда лямбда:
- Сохраняется в переменной или поле
- Передаётся другой функции, ожидающей тип функции
- Возвращается из встроенной функции
Запрет нелокальных возвратов
crossinline используется, когда встроенная лямбда будет вызвана в другом контексте выполнения (например, внутри другой лямбды или в другом потоке). Он сообщает компилятору: встроить эту лямбду, но не разрешать нелокальные возвраты из неё.
inline fun runAsync(crossinline block: () -> Unit) {
Thread {
block() // block is inlined but cannot use non-local return
}.start()
}Почему здесь опасны нелокальные возвраты
Если бы block мог использовать нелокальный return, он попытался бы выйти из функции, вызвавшей runAsync. Но к моменту запуска потока эта функция уже могла завершиться, что привело бы к неопределённому поведению. crossinline предотвращает это во время компиляции.
Объединение отключения встраивания и запрета нелокального возврата
Одна встроенная функция может одновременно использовать обычные параметры, а также параметры noinline и crossinline:
inline fun orchestrate(
crossinline setup: () -> Unit,
action: () -> Unit,
noinline teardown: () -> Unit
) {
Thread { setup() }.start()
action()
register(teardown)
}Ошибка компилятора без crossinline
Если передать встроенную лямбду в контекст другой лямбды без crossinline, компилятор выдаст сообщение: "Can't inline 'block' here: it may contain non-local returns. Add crossinline modifier."
Использование в стандартной библиотеке
Стандартная библиотека использует crossinline в таких функциях, как Sequence { }, и в некоторых конструкторах сопрограмм, гарантируя безопасный запуск переданной пользователем лямбды в другом контексте.
Отключение встраивания не отменяет встраивание остальных параметров
Пометка одного параметра как noinline не отключает встраивание всей функции. Тело функции и все остальные параметры-лямбды по-прежнему встраиваются. Только лямбда, помеченная noinline, сохраняет свою идентичность объекта.
Особенности производительности
noinline влечёт обычные затраты на выделение объекта лямбды для этого параметра. crossinline по-прежнему выполняет встраивание — единственное ограничение состоит в запрете нелокальных возвратов. Ни один из этих модификаторов не влияет на встраивание других параметров.
Сводная таблица
Сводка по модификаторам:
- Без модификатора → лямбда полностью встраивается, нелокальные возвраты разрешены
noinline→ лямбда сохраняется как объект и может быть сохранена или переданаcrossinline→ лямбда встраивается, нелокальные возвраты запрещены
Быстрая проверка
Когда необходимо использовать noinline для параметра-лямбды встроенной функции?
Повторение: noinline и crossinline
Главные выводы:
noinline: сохраняет одну лямбду как объект внутри функции, остальные части которой встраиваютсяcrossinline: встраивает лямбду, но запрещает нелокальные возвраты для безопасного использования в разных контекстах- Оба модификатора применяются к отдельным параметрам, а не ко всей функции
Часто задаваемые вопросы
Урок «Модификаторы noinline и crossinline» бесплатный?
Да — полный текст урока «Модификаторы noinline и crossinline» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Модификаторы noinline и crossinline»?
Управляйте встраиванием отдельных параметров-лямбд в inline-функциях. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Модификаторы noinline и crossinline»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- inline-функции: устранение накладных расходов лямбд
- Модификаторы noinline и crossinline
- Параметры типов reified: доступ к T во время выполнения
- Практические шаблоны reified: разбор, DI и сериализация