Встроенная функция объявляется с ключевым словом inline. Использование встроенной функции в Kotlin повышает производительность функции более высокого порядка. Встроенная функция указывает компилятору копировать параметры и функции в место вызова.
Виртуальная функция или локальная функция не может быть объявлена встроенной. Ниже приведены некоторые выражения и объявления, которые нигде не поддерживаются внутри встроенных функций:
- Объявление локальных классов
- Объявление внутренних вложенных классов
- Функциональные выражения
- Декларации местной функции
- Значение по умолчанию для необязательных параметров
Давайте посмотрим на базовый пример встроенной функции:
fun main(args: Array) {
inlineFunction({ println("calling inline functions")})
}
inline fun inlineFunction(myFun:() -> Unit ) {
myFun()
print("code inside inline function")
}
Выход:
calling inline functions code inside inline function
Нелокальный поток управления
Из встроенной функции мы можем вернуться из самого лямбда-выражения. Это также приведет к выходу из функции, в которой была вызвана встроенная функция. В этом случае литерал функции может иметь нелокальные операторы возврата.
fun main(args: Array) {
inlineFunction({ println("calling inline functions")
return},{ println("next parameter in inline functions")})
}
inline fun inlineFunction(myFun:() -> Unit, nxtFun:() -> Unit) {
myFun()
nxtFun()
print("code inside inline function")
}
Выход:
calling inline functions
Перекрестная аннотация
Чтобы предотвратить возврат из лямбда-выражения и самой встроенной функции, мы можем пометить лямбда-выражение как crossinline. Это вызовет ошибку компилятора, если он найдет оператор return внутри этого лямбда-выражения.
fun main(args: Array) {
inlineFunction({ println("calling inline functions")
return // compile time error
},{ println("next parameter in inline functions")})
}
inline fun inlineFunction(crossline myFun:() -> Unit, nxtFun:() -> Unit) {
myFun()
nxtFun()
print("code inside inline function")
}
Модификатор noinline
Во встроенной функции, когда мы хотим, чтобы некоторые лямбда-выражения, переданные во встроенную функцию, были встроенными, пометьте другой параметр функции модификатором noinline. Это используется для установки выражений, которые не будут встроены в вызов.
fun main(args: Array) {
inlineFunctionExample({ println("calling inline functions")},
{ println("next parameter in inline functions")} )
println("this is main function closing")
}
inline fun inlineFunctionExample(myFun:() -> Unit, noinline nxtFun:() -> Unit ) {
myFun()
nxtFun()
println("code inside inline function")
}
Выход:
calling inline functions next parameter in inline functions code inside inline function this is main function closing
Если встроенная функция не содержит ни одного параметра встроенной функции и параметров овеществленного типа, компилятор выдаст предупреждение.
