Ключевое слово inline
Ключевое слово inline используется для пометки функций,
которые должны быть встроены (inlined) на месте их вызова.
Это означает, что вместо обычного вызова функции
компилятор подставит тело функции непосредственно в место вызова.
Это особенно полезно для функций, принимающих лямбда-выражения
в качестве параметров, так как позволяет избежать создания
дополнительных объектов и улучшить производительность.
Синтаксис
kotlininline fun <имя_функции>(<параметры>): <возвращаемый_тип> {
// тело функции
}
kotlininline fun <T> <имя_функции>(<параметры>): <возвращаемый_тип> {
// тело функции с обобщенным типом
}
kotlininline fun <имя_функции>(crossinline <параметр>: () -> Unit): <возвращаемый_тип> {
// тело функции с crossinline параметром
}
kotlininline fun <имя_функции>(noinline <параметр>: () -> Unit): <возвращаемый_тип> {
// тело функции с noinline параметром
}
Пример
Создадим простую inline-функцию, которая выполняет переданное лямбда-выражение и измеряет время выполнения:
kotlininline 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")
}
После компиляции код будет преобразован примерно так:
kotlinval 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 для указания, что конкретный
лямбда-параметр не должен быть встроен:
kotlininline 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)
Результат выполнения кода:
kotlinList<Int> [4, 16]
Пример
Использование crossinline для лямбд, которые
должны быть выполнены в другом контексте:
kotlininline fun runAsync(crossinline block: () -> Unit) {
Thread {
block()
}.start()
}
runAsync {
println("Running in background thread")
}
Результат выполнения кода:
kotlin"Running in background thread"
Пример
Inline-функции с обобщенными типами:
kotlininline 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)
Результат выполнения кода:
kotlinInt 10
Когда использовать inline
Используйте inline для:
- Функций высшего порядка (принимающих лямбды)
- Небольших функций, где встраивание улучшит производительность
- Функций, которые работают с обобщенными типами в runtime
Не используйте inline для:
- Больших функций (увеличивает размер bytecode)
- Рекурсивных функций
- Функций, которые вызываются редко
Смотрите также
-
функции высшего порядка
fun,
которые принимают другие функции в качестве параметров