ENIGMA AI
ENIGMA AI
Kotlin Сложный

Зачем нужны inline-функции? Какие минусы?

Inline-функции в Kotlin

Проблема без inline:

fun measure(action: () -> Unit) {
    val start = System.currentTimeMillis()
    action()
    val end = System.currentTimeMillis()
    println("Time: ${end - start}ms")
}

measure { heavyOperation() }

// Компилируется в:
measure(new Function0() {
    @Override
    public void invoke() {
        heavyOperation();
    }
});
// Создаётся объект Function!

С inline:

inline fun measure(action: () -> Unit) {
    val start = System.currentTimeMillis()
    action()
    val end = System.currentTimeMillis()
    println("Time: ${end - start}ms")
}

measure { heavyOperation() }

// Код подставляется напрямую:
val start = System.currentTimeMillis()
heavyOperation()  // Без создания объекта!
val end = System.currentTimeMillis()
println("Time: ${end - start}ms")

Преимущества:

  1. Нет создания объектов — лямбды встраиваются
  2. Нет вызова invoke() — прямой код
  3. Non-local return — return из внешней функции
  4. Reified generics — доступ к типу в runtime

Non-local return:

inline fun forEach(list: List<Int>, action: (Int) -> Unit) {
    for (item in list) action(item)
}

fun findFirst() {
    forEach(listOf(1, 2, 3)) { item ->
        if (item == 2) return  // Выход из findFirst!
    }
    println("Not reached")
}

Reified:

inline fun <reified T> isInstance(value: Any): Boolean {
    return value is T  // Возможно только с reified
}

// Без inline это невозможно из-за type erasure

noinline и crossinline:

inline fun example(
    inlined: () -> Unit,
    noinline notInlined: () -> Unit,  // Не встраивать
    crossinline noReturn: () -> Unit   // Запретить non-local return
) {
    inlined()
    notInlined()  // Можно сохранить в переменную
    thread { noReturn() }  // Безопасно в другом контексте
}

Минусы:

  1. Увеличение размера кода — код дублируется
  2. Нельзя хранить лямбду — если не noinline
  3. Сложнее отладка — стектрейс менее понятен
  4. Рекурсия запрещена — inline-функция не может вызывать себя

Когда использовать:

  • Небольшие функции с лямбдами
  • Higher-order functions в hot path
  • Нужен reified generic
  • Нужен non-local return

Когда НЕ использовать:

  • Большие функции (раздувает код)
  • Без лямбд — нет смысла
  • Рекурсивные функции

Похожие вопросы

Готовитесь к собеседованию?

ENIGMA AI — невидимый ИИ-помощник для технических интервью

Попробовать бесплатно
Все вопросы