0Pricing
Kotlin Academy · Урок

Модификаторы 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 — локальная установка не требуется.

Все уроки этого курса

  1. inline-функции: устранение накладных расходов лямбд
  2. Модификаторы noinline и crossinline
  3. Параметры типов reified: доступ к T во время выполнения
  4. Практические шаблоны reified: разбор, DI и сериализация
← Назад к Kotlin Academy