До версии Kotlin 2.0 лямбды компилировались в анонимные классы, реализующие один из интерфейсов FunctionX:
val twice: (Int) -> Int = { value ->
value * 2
}
// лямбда является обычным классом который наследует интерфейс FunctionX
final class TwiceLambda implements Function1<Integer, Integer> {
// лямбды которые не захватывают переменные простые синглетоны, это нужно для переиспользования
public static final TwiceLambda INSTANCE = new TwiceLambda();
private TwiceLambda() {}
@Override
public Integer invoke(Integer value) {
return value * 2;
}
}Базовых интерфейсов для Kotlin лямбд всего 24, начиная с Function0, лямбда которая ничего не принимает, только возвращает результат, заканчивая Function22, лямбда которая принимает 22 параметра, также есть FunctionN для лямбд с переменным количеством аргументов.
Если лямбда захватывает переменную, то ее значение просто передается в конструктор:
val koeff = 2
val twice: (Int) -> Int = { value ->
value * koeff
}
final class TwiceLambda implements Function1<Integer, Integer> {
private final int koeff;
// в таком случае сложнее переиспользовать обьект лямбды
public TwiceLambda(int koeff) {
this.koeff = koeff;
}
...
}
Захват с var практически ничем не отличается, только значение кладется в IntRef, ObjectRef и тд, тут можно почитать.
Во второй части поговорим что стало с лямбдами в Kotlin 2.0+
