Как упоминалось в Сравнение с 4-м пунктом страницы Java, Kotlin имеет правильные типы функций, в отличие от SAM-преобразований Java.
What I означает, что если вы хотите принять функцию или какой-то код в Java, который вы можете вызвать внутри функции, вам нужен внешний интерфейс, имеющий ровно 1 метод, который знает о тип возвращаемого значения и подпись параметра .
Например, в Java:
// You can't create this unless you create FuncInterface defining its parameter and return type
MyFuncInterface a = (s) -> System.out.println(s);
interface MyFuncInterface {
public void myMethod(String s);
}
// now call a like
a.myMethod("Hello World"); // will print: Hello World
a.myMethod("Test"); // will print: Test
Хотя это не так в kotlin, вы можете создать лямбда без создания здесь.
Например, тот же код в Kotlin может быть преобразован в:
val a: (String) -> Unit = { println(it) }
// or like this: val a: (String) -> Unit = { s -> println(s) }
// call like this
a("Hello World") // will print: Hello World
a("Test") // will print: Test
Поскольку Kotlin имеет правильные типы функций, вы можете заставить функцию принимать тип функции или возврат, который затем называется функцией высшего порядка .
Концепция аналогична:
// This is a higher order functon, takes a callable function `f`
fun operatesFOn(num1: Int, num2: Int, f: (Int, Int) -> Int) {
// this types are useful as callbacks, instead of taking nums and passing them
// you can compute heavy tasks and when they complete call f with the result
return f(num1, num2)
}
// lambda can be put outside the parentheses if it is last parameter
// also is another higher order function which calls the lambda passed with the object it was called on as a parameter
operatesFOn(3, 4) { a, b -> a + b }.also { println(it) } // prints: 7
operatesFOn(5, 7) { a, b -> a * b }.also { println(it) } // prints: 35
Есть и другие классные модификаторы для функций более высокого порядка, таких как модификатор inline .
inline fun operatesFOn(num1: Int, num2: Int, f: (Int, Int) -> Int) {
return f(num1, num2)
}
Вышеупомянутый будет работать аналогично, но лямбда вместо этого будет встроена в сайт вызова во время компиляции, чтобы уменьшить стек вызовов, увеличивая производительность. как указано в документах :
Использование функций высшего порядка накладывает определенные штрафы во время выполнения: каждая функция является объектом, и она фиксирует замыкание, то есть те переменные, которые являются доступ в теле функции. Выделение памяти (как для функциональных объектов, так и для классов) и виртуальные вызовы приводят к накладным расходам времени выполнения.