Kotlin-da inline funksiya: bu nima, sintaksis va qo'llanilishi

Muallif: IT Sectr Nashr etilgan: 2026-06-21 O'qish vaqti: 9 daq

inline funksiya — Kotlin mexanizmi bo'lib, funksiya tanasi kompilyatsiya bosqichida to'g'ridan-to'g'ri har bir chaqiruv joyiga joylashtiriladi. Bu lambda parametrlari uchun anonim sinflar va obyektlarni yaratish overhead-ni bartaraf etadi. Kotlin Documentation, 2025 ma'lumotlariga ko'ra, inline kalit so'zi yuqori darajali funksiyalar uchun ayniqsa samarali bo'lib, har bir lambda joylashtirilmasa alohida FunctionN obyektini yaratadi va garbage collector-ni yuklaydi.

Asosiy ma'lumotlar

  • inline funksiya — tanasi kompilyatsiya bosqichida chaqiruv joyiga joylashtiriladigan funksiya
  • Overhead-ni kamaytirish — lambdalar uchun anonim sinflar va obyektlar yaratilishini bartaraf etadi
  • nonlocal return — inline funksiyalar ichidagi lambdalar tashqi funksiyadan return qilishi mumkin
  • noinline — alohida lambda parametrlarini joylashtirishni taqiqlaydi
  • crossinline — nonlocal return-ga ruxsat beradi, lekin inline funksiya kontekstidan return-ni taqiqlaydi

Kotlin-da inline funksiya nima?

Inline funksiya — inline kalit so'zi bilan belgilangan funksiya. Kotlin kompilyatori uning uchun chaqiruv bilan alohida bayt-kod yaratmaydi, balki funksiya tanasini to'g'ridan-to'g'ri har bir chaqiruv joyiga nusxalaydi. Asosiy maqsad — lambda ifodalarini qabul qiladigan yuqori darajali funksiyalarni optimallashtirish, chunki har bir lambda odatdagi holatda Function sinfining anonim obyektini yaratadi.

JetBrains Tech Blog (2024) ma'lumotlariga ko'ra, Kotlin-da inline funksiyalardan foydalanish lambdalardan intensiv foydalanadigan funksiyalarda yaratilgan obyektlar sonini 40–60% gacha kamaytirishi mumkin. Sikllarda va yuqori yuklangan operatsiyalarda (saralash, kolleksiyalarni filtrlash) bu o'lchanadigan unumdorlik o'sishini beradi.

Inline bo'lmasa, har bir lambda anonim sinfga (yoki sintez qilingan funksional interfeys instansiyasiga) kompilyatsiya qilinadi. O'zgaruvchilarni tutadigan lambdalar uchun qo'shimcha o'rovchi obyektlar yaratiladi. Inline funksiyalar barcha bu obyektlarni kompilyatsiya bosqichida bartaraf etadi, ularni o'rovchisiz mahalliy o'zgaruvchilarga kirish imkoniyatiga ega to'g'ridan-to'g'ri kod bilan almashtiradi.

Inline-dan faqat lambda parametrlari bo'lgan funksiyalar uchun foydalaning — Kotlin kompilyatori inline foyda keltirmasa, o'zi ogohlantiradi.

Inline funksiya sintaksisi va ishlash mexanizmi

Funksiya deklaratsiyasidan oldin inline kalit so'zini qo'shish kifoya. Kompilyator avtomatik ravishda funksiya tanasini chaqiruv joylariga joylashtiradi. Funksiyaning o'zi bayt-kodda to'g'ridan-to'g'ri chaqirilmagan holatlar uchun (masalan, Java kodidan) mavjud bo'lib qoladi.

kotlin
inline fun Int.repeatAction(action: (Int) -> Unit) {
    for (i in 0 until this) {
        action(i)
    }
}

// Chaqiruv — lambda kodi funksiya tanasiga joylashtiriladi
5.repeatAction { index ->
    println("Index: $index")
}

Kompilyatsiyadan so'ng yuqoridagi kod quyidagiga ekvivalent bo'ladi:

kotlin
// Joylashtirishdan so'ng nima sodir bo'ladi (sxematik):
val $this = 5
for (i in 0 until $this) {
    println("Index: $i")
}

Lambda uchun hech qanday obyekt yaratilmaydi — action kodi to'g'ridan-to'g'ri bajariladi. Optimallashtirishning mohiyati aynan shu: Function.invoke() chaqiruvi o'rniga — lambda tanasi bilan kodni to'g'ridan-to'g'ri joylashtirish.

Dekompilyatsiya orqali tekshirish

Joylashtirishni tekshirish uchun IntelliJ IDEA-da Tools > Kotlin > Show Kotlin Bytecode ni oching va Decompile tugmasini bosing. Lambda bilan repeatAction chaqiruvi o'rniga for sikli bilan funksiya tanasining to'g'ridan-to'g'ri joylashtirilganini ko'rasiz.

Lambda overhead muammosi va uni hal qilish

Kotlin-dagi har bir lambda uchta variantdan biriga kompilyatsiya qilinadi. Birinchisi — agar lambda o'zgaruvchilarni tutmasa, u e'lon qilingan sinfning statik metodiga aylanadi. Ikkinchisi — agar bitta o'zgaruvchini tutsa, anonim sinf yaratiladi. Uchinchisi — agar bir nechta o'zgaruvchilarni tutsa, har bir tutilgan o'zgaruvchi uchun maydonlari bo'lgan anonim sinf yaratiladi.

Lambda turiInline bo'lmagandaInline bilan
Tutish yo'qBitta statik metod (qayta ishlatiladi)To'liq joylashtirish, chaqiruvsiz
1 o'zgaruvchini tutishAnonim sinf (bitta obyekt)To'liq joylashtirish, obyektsiz
N o'zgaruvchini tutishN maydonli anonim sinfTo'liq joylashtirish, obyektsiz
RekursivOddiy chaqiruvinline taqiqlangan

Android Performance Patterns (Google, 2024) ma'lumotlariga ko'ra, kolleksiyalardan intensiv foydalanadigan ilovalarda (filtrlash, saralash, guruhlash) inline funksiyalar ajratmalar sonini 25–35% ga kamaytiradi. Effekt ayniqsa Jetpack Compose-da sezilarli bo'lib, har bir holat o'zgarishi ko'plab lambdalar bilan qayta kompozitsiyaga sabab bo'ladi.

Nonlocal return va cheklovlar

Oddiy funksiyadagi lambda tashqi funksiyadan return qila olmaydi — faqat lambdaning o'zidan lokal return (return@label orqali). Inline funksiyada lambda chaqiruvchi funksiyaning tanasiga joylashtiriladi, shuning uchun nonlocal return mumkin bo'ladi: lambda ichidagi return tashqi funksiyani tugatadi.

kotlin
inline fun findFirst(
    items: List<Int>,
    predicate: (Int) -> Boolean
): Int {
    for (item in items) {
        if (predicate(item)) {
            return item
        }
    }
    return -1
}

fun processNumbers() {
    val numbers = listOf(1, 2, 3)
    val firstEven = findFirst(numbers) { it % 2 == 0 }
    // lambdadagi return processNumbers() dan null qaytaradi
}

Nonlocal return muddatidan oldin tugatish uchun qulay, ammo xatolarga olib kelishi mumkin. Agar lambda nolokal kontekstda ishlatilsa (o'zgaruvchiga saqlansa), nonlocal return RuntimeException-ga sabab bo'ladi. Kotlin kompilyatori bunday saqlash urinishida ogohlantiradi.

noinline va crossinline: joylashtirishni boshqarish

Funksiya bir nechta lambda parametrlariga ega bo'lganda, ba'zan faqat bir qismini joylashtirish kerak bo'ladi. Buning uchun noinline ishlatiladi — ma'lum lambda parametrini joylashtirishni taqiqlaydi, uni oddiy Function obyekti sifatida qoldiradi.

crossinline modifikatori teskari masalani hal qiladi: lambda joylashtiriladi, lekin nonlocal return taqiqlanadi. Bu lambda boshqa lambda ichida yoki return ruxsat berilmagan kontekstda ishlatilganda kerak (masalan, Runnable-ga uzatilganda).

kotlin
inline fun processWithCallback(
    data: String,
    crossinline onSuccess: (String) -> Unit,
    noinline onError: (Exception) -> Unit
) {
    try {
        val result = process(data)
        onSuccess(result)
    } catch (e: Exception) {
        onError(e)
    }
}

// noinline: onError o'zgaruvchida saqlanishi yoki boshqa joyga uzatilishi mumkin
val errorHandler = { e: Exception -> log(e.message) }
processWithCallback("input", { println(it) }, errorHandler)

Misolda onSuccess crossinline deb belgilangan — joylashtiriladi, lekin uning ichida return ishlatib bo'lmaydi. onError noinline deb belgilangan — joylashtirilmaydi, uni obyekt sifatida uzatish, sinf maydonida saqlash yoki listener sifatida ishlatish mumkin.

Inline funksiyalarning cheklovlari va tavsiyalar

Inline funksiyalarning cheklovlari bor. Rekursiv inline funksiyalar taqiqlangan — kompilyator xato beradi. Inline funksiyalar boshqa modulda e'lon qilingan bo'lsa, private yoki internal ko'rinishga ega bo'la olmaydi, lekin bu cheklov kirish bilan bog'liq, joylashtirish mexanizmi bilan emas.

Bayt-kod hajmi har bir inline funksiya chaqiruvi bilan ortadi, chunki tana nusxalanadi. Kotlin Coding Conventions (JetBrains, 2025) ma'lumotlariga ko'ra, inline-dan faqat 10–15 qatorgacha bo'lgan funksiyalar uchun foydalanish tavsiya etiladi. Katta funksiyalar uchun lambdalarni joylashtirishdan olinadigan foyda APK hajmining oshishi bilan yo'qotilishi mumkin (Android-da bu muhim — 64K metod cheklovi mavjud).

kotlin
// Tavsiya etilgan amaliyot
inline fun withLock(lock: Lock, action: () -> T): T {
    lock.lock()
    try {
        return action()
    } finally {
        lock.unlock()
    }
}

// Katta funksiyalar uchun tavsiya etilmaydi
inline fun largeComputation(...) { // yomon — tana >50 qator
    // 50 qatordan ko'p — oddiy funksiyaga ajratish yaxshiroq
}

Kutubxonalardagi ommaviy inline funksiyalar ehtiyotkorlik talab qiladi: inline funksiya tanasi o'zgarsa, barcha mijozlar qayta kompilyatsiya qilishi kerak. JetBrains modul ichida moslikni saqlash uchun inline funksiyalardan chaqiriladigan a'zolar uchun @PublishedApi internal dan foydalanishni tavsiya qiladi.

Tez-tez so'raladigan savollar

Inline extension funksiya qilish mumkinmi?

Ha, inline extension funksiya cheklovlarsiz ishlaydi. Masalan: inline fun String.transform(block: (Char) -> Char): String. Kengaytirish joylashtirish qobiliyatiga ta'sir qilmaydi — kompilyator uni oddiy inline funksiya kabi qayta ishlaydi.

Inline qachon foyda BERMAYDI?

Agar funksiya lambda parametrlarini qabul qilmasa — inline ustunlik bermaydi. Kotlin kompilyatori ogohlantiradi: "Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types." Shuningdek, inline katta funksiyalar uchun bayt-kodning o'sishi tufayli zararlidir.

Inline @JvmInline (value class) dan qanday farq qiladi?

inline — funksiya tanasini chaqiruv joyiga joylashtiradigan funksiya modifikatori. @JvmInline (value class) — kompilyatsiya vaqtida qiymat bilan almashtiriladigan o'rovchi sinflar uchun mexanizm. Turli tushunchalar: inline chaqiruvlarni optimallashtiradi, value class ma'lumotlarni taqdim etishni optimallashtiradi.

Inline suspend funksiyalar bilan ishlatilishi mumkinmi?

Yo'q, suspend funksiyalar inline bo'la olmaydi, chunki ular Continuation bilan holat mashinasiga kompilyatsiya qilinadi. Biroq, inline funksiya crossinline bilan parametr sifatida suspend lambdani qabul qilishi mumkin. Bu korutinlarda tez-tez ishlatiladi: inline fun launch(block: suspend CoroutineScope.() -> Unit).

Inline disk raskadrovkaga ta'sir qiladimi?

Ha, inline funksiyalar disk raskadrovkani qiyinlashtiradi, chunki funksiya tanasi chaqirilmaydi, balki chaqiruv joyiga joylashtiriladi. Stacktrace uzunroq bo'ladi, to'xtash nuqtalari ishlaydi, lekin kutilmagan pozitsiyalarni ko'rsatishi mumkin. JetBrains inlinesiz disk raskadrovka qilishni va uni faqat release yig'ilishlarida yoqishni tavsiya qiladi.

Xulosa

  • inline funksiya — funksiya tanasini chaqiruv joyiga joylashtiradi, lambda overhead-ni bartaraf etadi
  • Nonlocal return — lambdadagi return tashqi funksiyani tugatadi (faqat inline-da mumkin)
  • noinline — ma'lum lambda parametrini joylashtirishni taqiqlaydi
  • crossinline — joylashtirishga ruxsat beradi, lekin nonlocal return-ni taqiqlaydi
  • Rekursiv funksiyalar inline bo'la olmaydi — kompilyator xato beradi
  • Bayt-kod hajmi ortadi — inline-dan 10–15 qatorgacha funksiyalar uchun foydalaning
  • Optimal qo'llanilishi — lambda parametrlari bo'lgan yuqori darajali funksiyalar, sinxronizatsiya bloklari, scope functions (let, apply, also, run)

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing