НОВИНКА!
Занимательная математика от Трепачёва. Присоединяйтесь к нам!
26 of 1310 menu

Ключевое слово inline

Ключевое слово inline используется для пометки функций, которые должны быть встроены (inlined) на месте их вызова. Это означает, что вместо обычного вызова функции компилятор подставит тело функции непосредственно в место вызова. Это особенно полезно для функций, принимающих лямбда-выражения в качестве параметров, так как позволяет избежать создания дополнительных объектов и улучшить производительность.

Синтаксис

inline fun <имя_функции>(<параметры>): <возвращаемый_тип> { // тело функции }
inline fun <T> <имя_функции>(<параметры>): <возвращаемый_тип> { // тело функции с обобщенным типом }
inline fun <имя_функции>(crossinline <параметр>: () -> Unit): <возвращаемый_тип> { // тело функции с crossinline параметром }
inline fun <имя_функции>(noinline <параметр>: () -> Unit): <возвращаемый_тип> { // тело функции с noinline параметром }

Пример

Создадим простую inline-функцию, которая выполняет переданное лямбда-выражение и измеряет время выполнения:

inline fun measureTime(block: () -> Unit) { val start = System.currentTimeMillis() block() val end = System.currentTimeMillis() println("Execution time: ${end - start} ms") } // Использование функции measureTime { var sum = 0 for (i in 1..1000) { sum += i } println("Sum: $sum") }

После компиляции код будет преобразован примерно так:

val start = System.currentTimeMillis() var sum = 0 for (i in 1..1000) { sum += i } println("Sum: $sum") val end = System.currentTimeMillis() println("Execution time: ${end - start} ms")

Пример

Использование noinline для указания, что конкретный лямбда-параметр не должен быть встроен:

inline fun processData( data: List<Int>, noinline validator: (Int) -> Boolean, transformer: (Int) -> Int ): List<Int> { return data.filter(validator).map(transformer) } val numbers = listOf(1, 2, 3, 4, 5) val isEven = { n: Int -> n % 2 == 0 } val squared = { n: Int -> n * n } val res = processData(numbers, isEven, squared) println(res)

Результат выполнения кода:

List<Int> [4, 16]

Пример

Использование crossinline для лямбд, которые должны быть выполнены в другом контексте:

inline fun runAsync(crossinline block: () -> Unit) { Thread { block() }.start() } runAsync { println("Running in background thread") }

Результат выполнения кода:

"Running in background thread"

Пример

Inline-функции с обобщенными типами:

inline fun <T> T.applyIf(condition: Boolean, block: T.() -> T): T { return if (condition) block() else this } val number = 5 val res = number.applyIf(number > 0) { this * 2 } println(res)

Результат выполнения кода:

Int 10

Когда использовать inline

Используйте inline для:

  • Функций высшего порядка (принимающих лямбды)
  • Небольших функций, где встраивание улучшит производительность
  • Функций, которые работают с обобщенными типами в runtime

Не используйте inline для:

  • Больших функций (увеличивает размер bytecode)
  • Рекурсивных функций
  • Функций, которые вызываются редко

Смотрите также

  • функции высшего порядка fun,
    которые принимают другие функции в качестве параметров
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить