0Pricing
Kotlin Academy · Урок

inline-функции: устранение накладных расходов лямбд

Помечайте функции как inline, чтобы не создавать объекты для параметров-лямбд.

«inline-функции: устранение накладных расходов лямбд» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Что такое встроенная функция

Обычно лямбда, переданная функции, компилируется в анонимный класс. При каждом вызове выделяется новый объект, что требует памяти и времени. Ключевое слово inline указывает компилятору скопировать тело функции вместе с её аргументами-лямбдами непосредственно в место вызова.

Объявление встроенной функции

Добавьте модификатор inline перед fun:

inline fun measureTime(block: () -> Unit): Long {
    val start = System.nanoTime()
    block()
    return System.nanoTime() - start
}

Как компилятор переписывает вызов

Вызов вроде measureTime { doWork() } на уровне байткода превращается во встроенное тело measureTime, вставленное непосредственно в место вызова: объект лямбды вообще не выделяется.

Когда использовать встраивание

Используйте inline, когда:

  • Функция принимает один или несколько параметров-лямбд
  • Она часто вызывается на критических по производительности участках (в тесных циклах, в composable-функциях)
  • Вам нужны параметры типов reified (они рассматриваются далее)

Пример сравнения производительности

Без inline каждый вызов функции высшего порядка выделяет объект лямбды. С ним JVM видит последовательный код — без выделения памяти и виртуальной диспетчеризации.

inline fun repeat(n: Int, block: () -> Unit) {
    for (i in 0 until n) block()
}

Нелокальные возвраты

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

inline fun forEach(list: List<Int>, block: (Int) -> Unit) {
    for (item in list) block(item)
}

fun findFirst(list: List<Int>): Int {
    forEach(list) { if (it > 5) return it }  // returns from findFirst
    return -1
}

Ограничения встраивания

Встроенные функции нельзя сохранять в переменных или передавать как объекты, поскольку во время выполнения они не существуют как самостоятельные сущности. Нельзя вызвать f(::measureTime), если f ожидает ссылку на функцию с такой сигнатурой.

Встраивание конвейеров коллекций

Функции стандартной библиотеки map, filter, forEach и другие являются inline. Поэтому их объединение в цепочку не создаёт дополнительных объектов замыканий для каждого элемента.

val result = (1..1_000_000)
    .filter { it % 2 == 0 }   // inline
    .map { it * it }           // inline
    .take(10)

Компромисс между размером кода и производительностью

Каждое место вызова получает копию встроенного кода. Если тело функции большое и вызывается из многих мест, размер байткода увеличивается. Предпочитайте inline для небольших, часто вызываемых лямбд.

Взаимодействие с функциями companion и верхнего уровня

inline работает с функциями верхнего уровня и функциями-членами. Он не работает со свойствами или конструкторами. Функция должна быть видима в месте вызова (обычно иметь модификатор public или internal).

Примеры из стандартной библиотеки

Уже знакомые вам функции, являющиеся inline: let, run, apply, also, with, use, synchronized, lazy (вариант с блоком). Именно модификатор inline делает их лямбды не требующими дополнительных затрат.

Быстрая проверка

Каково главное преимущество пометки функции высшего порядка как inline?

Повторение: встроенные функции

Главные выводы:

  • inline устраняет выделение объектов лямбд
  • Позволяет выполнять нелокальные возвраты из лямбд
  • Требуется для параметров типов reified
  • Лучше всего подходит для небольших, часто вызываемых функций высшего порядка
  • Все функции областей действия стандартной библиотеки являются inline

Часто задаваемые вопросы

Урок «inline-функции: устранение накладных расходов лямбд» бесплатный?

Да — полный текст урока «inline-функции: устранение накладных расходов лямбд» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «inline-функции: устранение накладных расходов лямбд»?

Помечайте функции как inline, чтобы не создавать объекты для параметров-лямбд. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «inline-функции: устранение накладных расходов лямбд»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

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

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