Зачем нужен inline в Kotlin
Что проверяют
Понимаете ли вы, что подстановка нужна ради лямбд, и знаете ли, что она открывает reified и нелокальный возврат.
Как отвечать
inline подставляет тело функции в место вызова. Выигрыш не в экономии на самом вызове: обычная функция, принимающая лямбду, создаёт для неё объект, а при подстановке код лямбды оказывается прямо в вызывающем методе, и объекта нет.
inline fun <T> withLock(lock: Lock, body: () -> T): T {
lock.lock()
try { return body() } finally { lock.unlock() }
}Два следствия, которых иначе не получить:
- нелокальный возврат:
returnвнутри лямбды выходит из внешней функции; - реифицированные обобщения:
inline fun <reified T> parse(json: String): Tпозволяет обратиться кT::classво время выполнения, хотя обычно тип стирается.
Модификаторы параметров: noinline, если лямбду нужно сохранить или передать дальше как значение; crossinline, если она вызывается из другого контекста и нелокальный возврат из неё недопустим.
Когда не нужно: у функции без лямбд выигрыша нет, а тело копируется в каждое место вызова и раздувает байт-код. Компилятор на такой inline прямо предупреждает. Смысл есть у коротких функций высшего порядка, как let, run, apply, forEach в стандартной библиотеке.
Где спотыкаются
Ставят inline везде подряд ради скорости.
Не знают про reified и передают Class<T> параметром.
Путают noinline и crossinline.
Не могут объяснить, почему подставленная функция не видит приватные члены вызывающего класса.