Kotlin-də inline funksiya: bu nədir, sintaksis və tətbiqi

Müəllif: IT Sectr Dərc olunub: 2026-06-21 Oxuma vaxtı: 9 dəq

inline funksiya — Kotlin mexanizmi, bu zaman funksiyanın gövdəsi kompilasiya mərhələsində birbaşa hər çağrı yerinə yerləşdirilir. Bu, lambda parametrləri üçün anonim siniflərin və obyektlərin yaradılması overhead-ini aradan qaldırır. Kotlin Documentation, 2025-ə görə, inline açar sözü xüsusilə yüksək səviyyəli funksiyalar üçün effektivdir, burada hər lambda yerləşdirmə olmadan ayrıca FunctionN obyekti yaradır və garbage collector-u yükləyir.

Əsas məqamlar

  • inline funksiya — gövdəsi kompilasiya mərhələsində çağrı yerinə yerləşdirilən funksiya
  • Overhead-in azaldılması — lambdalar üçün anonim sinif və obyekt yaradılmasını aradan qaldırır
  • nonlocal return — inline funksiyalar daxilindəki lambdalar xarici funksiyadan return edə bilər
  • noinline — ayrı-ayrı lambda parametrlərinin yerləşdirilməsini qadağan edir
  • crossinline — nonlocal return-ə icazə verir, lakin inline funksiya kontekstindən return-ü qadağan edir

Kotlin-də inline funksiya nədir?

Inline funksiya — inline açar sözü ilə işarələnmiş funksiyadır. Kotlin kompilatoru onun üçün çağrı ilə ayrıca bayt-kod yaratmır, əksinə funksiyanın gövdəsini birbaşa hər çağrı yerinə kopyalayır. Əsas məqsəd — lambda ifadələrini qəbul edən yüksək səviyyəli funksiyaların optimallaşdırılmasıdır, çünki hər lambda normal vəziyyətdə Function sinfinin anonim obyektini yaradır.

JetBrains Tech Blog (2024)-ə görə, Kotlin-də inline funksiyaların istifadəsi lambdalardan intensiv istifadə edən funksiyalarda yaradılan obyektlərin sayını 40–60% azalda bilər. Dövrlərdə və yüksək yüklü əməliyyatlarda (çeşidləmə, kolleksiyaların filtrasiyası) bu, ölçülə bilən performans artımı verir.

Inline olmadan hər lambda anonim sinifə (və ya sintez edilmiş funksional interfeysin instansına) kompilasiya olunur. Dəyişənləri tutan lambdalar üçün əlavə sarğı obyektləri yaradılır. Inline funksiyalar bütün bu obyektləri kompilasiya mərhələsində aradan qaldırır, onları sarğısız lokal dəyişənlərə girişi olan birbaşa kodla əvəz edir.

Inline-dən yalnız lambda parametrləri olan funksiyalar üçün istifadə edin — Kotlin kompilatoru inline fayda vermədikdə özü xəbərdarlıq edir.

Inline funksiyanın sintaksisi və iş mexanizmi

Funksiya bəyannaməsindən əvvəl inline açar sözünü əlavə etmək kifayətdir. Kompilator avtomatik olaraq funksiyanın gövdəsini çağrı yerlərinə yerləşdirir. Funksiyanın özü bayt-kodda birbaşa çağrılmadığı hallar üçün (məsələn, Java kodundan) mövcud olaraq qalır.

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

// Çağrı — lambda kodu funksiyanın gövdəsinə yerləşdirilir
5.repeatAction { index ->
    println("Index: $index")
}

Kompilasiyadan sonra yuxarıdakı kod aşağıdakına ekvivalent olacaq:

kotlin
// Yerləşdirmədən sonra nə baş verir (sxematik):
val $this = 5
for (i in 0 until $this) {
    println("Index: $i")
}

Lambda üçün heç bir obyekt yaradılmır — action kodu birbaşa icra olunur. Optimallaşdırmanın mahiyyəti budur: Function.invoke() çağrısı əvəzinə — lambda gövdəsi ilə kodun birbaşa yerləşdirilməsi.

Dekompilyasiya vasitəsilə yoxlama

Yerləşdirməni yoxlamaq üçün IntelliJ IDEA-da Tools > Kotlin > Show Kotlin Bytecode açın və Decompile düyməsini basın. Görəcəksiniz ki, lambda ilə repeatAction çağrısı əvəzinə for dövrü ilə funksiya gövdəsinin birbaşa yerləşdirilməsi generasiya olunur.

Lambda overhead problemi və həlli

Kotlin-də hər lambda üç variantdan birinə kompilasiya olunur. Birinci — lambda dəyişənləri tutmursa, o, bəyan olunduğu sinfin statik metoduna çevrilir. İkinci — bir dəyişəni tutursa, anonim sinif yaradılır. Üçüncü — bir neçə dəyişəni tutursa, hər tutulan dəyişən üçün sahələri olan anonim sinif yaradılır.

Lambda növüInline olmadanInline ilə
Tutma yoxdurBir statik metod (təkrar istifadə olunur)Tam yerləşdirmə, çağrısız
1 dəyişənin tutulmasıAnonim sinif (bir obyekt)Tam yerləşdirmə, obyektsiz
N dəyişənin tutulmasıN sahəli anonim sinifTam yerləşdirmə, obyektsiz
RekursivAdi çağrıinline qadağandır

Android Performance Patterns (Google, 2024)-ə görə, kolleksiyalardan intensiv istifadə edən tətbiqlərdə (filtrasiya, çeşidləmə, qruplaşdırma) inline funksiyalar alokasiyaların sayını 25–35% azaldır. Effekt xüsusilə Jetpack Compose-da nəzərə çarpır, burada hər vəziyyət dəyişikliyi çoxsaylı lambdalarla yenidən kompozisiyaya səbəb olur.

Nonlocal return və məhdudiyyətlər

Adi funksiyadakı lambda xarici funksiyadan return edə bilməz — yalnız lambdanın özündən lokal return (return@label vasitəsilə). Inline funksiyada lambda çağıran funksiyanın gövdəsinə yerləşdirilir, buna görə də nonlocal return mümkün olur: lambda daxilindəki return xarici funksiyanı bitirir.

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 }
    // lambdadakı return processNumbers() funksiyasından null qaytarardı
}

Nonlocal return vaxtından əvvəl bitirmək üçün rahatdır, lakin səhvlərə səbəb ola bilər. Lambda qeyri-lokal kontekstdə istifadə olunarsa (dəyişənə saxlanılarsa), nonlocal return RuntimeException-a səbəb olacaq. Kotlin kompilatoru belə saxlama cəhdində xəbərdarlıq edir.

noinline və crossinline: yerləşdirmənin idarə edilməsi

Funksiyanın bir neçə lambda parametri olduqda, bəzən yalnız bir hissəsini yerləşdirmək lazım gəlir. Bunun üçün noinline istifadə olunur — müəyyən lambda parametrinin yerləşdirilməsini qadağan edir, onu adi Function obyekti kimi saxlayır.

crossinline modifikatoru əks məsələni həll edir: lambda yerləşdirilir, lakin nonlocal return qadağan edilir. Bu, lambda başqa lambda daxilində və ya return-ün icazə verilmədiyi kontekstdə istifadə edildikdə lazımdır (məsələn, Runnable-ə ötürülərkən).

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 dəyişəndə saxlanıla və ya başqa yerə ötürülə bilər
val errorHandler = { e: Exception -> log(e.message) }
processWithCallback("input", { println(it) }, errorHandler)

Nümunədə onSuccess crossinline olaraq işarələnib — yerləşdiriləcək, lakin onun daxilində return istifadə etmək olmaz. onError noinline olaraq işarələnib — yerləşdirilmir, onu obyekt kimi ötürmək, sinif sahəsində saxlamaq və ya listener kimi istifadə etmək olar.

Inline funksiyaların məhdudiyyətləri və tövsiyələr

Inline funksiyaların məhdudiyyətləri var. Rekursiv inline funksiyalar qadağandır — kompilator xəta verəcək. Inline funksiyalar başqa modulda bəyan olunubsa, private və ya internal görünürlüyünə malik ola bilməz, lakin bu məhdudiyyət girişlə bağlıdır, yerləşdirmə mexanizmi ilə deyil.

Bayt-kodun ölçüsü hər inline funksiya çağrısı ilə artır, çünki gövdə kopyalanır. Kotlin Coding Conventions (JetBrains, 2025)-ə görə, inline-dən yalnız 10–15 sətirə qədər olan funksiyalar üçün istifadə etmək tövsiyə olunur. Böyük funksiyalar üçün lambdaların yerləşdirilməsindən əldə olunan qazanc APK ölçüsünün artması ilə itirilə bilər (Android-də bu kritikdir — 64K metod limiti var).

kotlin
// Tövsiyə olunan təcrübə
inline fun withLock(lock: Lock, action: () -> T): T {
    lock.lock()
    try {
        return action()
    } finally {
        lock.unlock()
    }
}

// Böyük funksiyalar üçün tövsiyə edilmir
inline fun largeComputation(...) { // pis — gövdə >50 sətir
    // 50 sətirdən çox — adi funksiyaya ayırmaq daha yaxşıdır
}

Kitabxanalardakı ictimai inline funksiyalar ehtiyat tələb edir: inline funksiyanın gövdəsi dəyişərsə, bütün müştərilər yenidən kompilasiya etməlidir. JetBrains, modul daxilində uyğunluğu qorumaq üçün inline funksiyalardan çağrılan üzvlər üçün @PublishedApi internal istifadəsini tövsiyə edir.

Tez-tez verilən suallar

Inline extension function etmək olarmı?

Bəli, inline extension function məhdudiyyətsiz işləyir. Məsələn: inline fun String.transform(block: (Char) -> Char): String. Genişləndirmə yerləşdirmə qabiliyyətinə təsir etmir — kompilator onu adi inline funksiya kimi emal edir.

Inline nə vaxt fayda VERMİR?

Əgər funksiya lambda parametrləri qəbul etmirsə — inline üstünlük vermir. Kotlin kompilatoru xəbərdarlıq edir: "Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types." Həmçinin inline böyük funksiyalar üçün bayt-kodun artması səbəbindən zərərlidir.

Inline @JvmInline (value class)-dan nə ilə fərqlənir?

inline — funksiyanın gövdəsini çağrı yerinə yerləşdirən funksiya modifikatorudur. @JvmInline (value class) — kompilasiya zamanı dəyərlə əvəz olunan sarğı sinifləri üçün mexanizmdir. Fərqli konsepsiyalar: inline çağrıları optimallaşdırır, value class məlumat təqdimatını optimallaşdırır.

Inline suspend-funksiyalarla istifadə oluna bilərmi?

Xeyr, suspend-funksiyalar inline ola bilməz, çünki onlar Continuation ilə vəziyyət maşınına kompilasiya olunur. Lakin inline funksiya crossinline ilə parametr kimi suspend-lambda qəbul edə bilər. Bu, korutinlərdə tez-tez istifadə olunur: inline fun launch(block: suspend CoroutineScope.() -> Unit).

Inline debug-a təsir edirmi?

Bəli, inline funksiyalar debug-u çətinləşdirir, çünki funksiyanın gövdəsi çağrılmır, əksinə çağrı yerinə yerləşdirilir. Stacktrace daha uzun olur, dayanma nöqtələri işləyir, lakin gözlənilməz mövqelər göstərə bilər. JetBrains inline olmadan debug etməyi və onu yalnız release qurğularında aktivləşdirməyi tövsiyə edir.

Nəticə

  • inline funksiya — funksiyanın gövdəsini çağrı yerinə yerləşdirir, lambda overhead-ini aradan qaldırır
  • Nonlocal return — lambdadakı return xarici funksiyanı bitirir (yalnız inline-da mümkündür)
  • noinline — müəyyən lambda parametrinin yerləşdirilməsini qadağan edir
  • crossinline — yerləşdirməyə icazə verir, lakin nonlocal return-ü qadağan edir
  • Rekursiv funksiyalar inline ola bilməz — kompilator xəta verir
  • Bayt-kod ölçüsü artır — inline-dən 10–15 sətirə qədər funksiyalar üçün istifadə edin
  • Optimal tətbiq — lambda parametrləri olan yüksək səviyyəli funksiyalar, sinxronizasiya blokları, scope functions (let, apply, also, run)

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun