← Back to Kotlin Course | Chapter 9: Lambdas & Higher-Order Functions | Lesson 6 of 6

Inline Functions क्या हैं

एक inline function compile time पर हर उस जगह सीधे copy-paste हो जाता है जहां इसे call किया जाता है, जो lambdas वाले छोटे helper functions को तेज़ चला सकता है।
Syntax
kotlin
inline fun functionName(action: () -> Unit) {
    // body and lambda are copied to the call site
    action()
}

Declaring an Inline Function

fun से पहले inline जोड़ना compiler को हर call site पर एक normal function call के बजाय function के compiled code को सीधे insert करने के लिए कहता है, जो इसके function-type parameters के लिए अतिरिक्त lambda object allocation से बचाता है।

उदाहरण: Declaring an Inline Function

markup
inline fun measureAndRun(action: () -> Unit) {
    // Declare a read-only variable `start`, set to `System.currentTimeMillis()`
    val start = System.currentTimeMillis()
    action()
    // Declare a read-only variable `time`, set to `System.currentTimeMillis() - start`
    val time = System.currentTimeMillis() - start
    // Print "Took ${time}ms" to the console, with a trailing newline
    println("Took ${time}ms")
}

// Entry point: execution of the program starts here
fun main() {
    measureAndRun {
        // Print "Doing some work" to the console, with a trailing newline
        println("Doing some work")
    }
}

Why Inlining Avoids Overhead

आमतौर पर, कोई lambda पास करना पीछे एक function interface implement करने वाला एक object बनाता है; inlining lambda के code को सीधे call site में copy करके इस indirection को पूरी तरह हटा देता है।

उदाहरण: Why Inlining Avoids Overhead

markup
inline fun repeatAction(times: Int, action: (Int) -> Unit) {
    // Loop over `0 until times`, binding each item to `i`
    for (i in 0 until times) {
        action(i)
    }
}

// Entry point: execution of the program starts here
fun main() {
    repeatAction(3) { index ->
        // Print "Iteration $index" to the console, with a trailing newline
        println("Iteration $index")
    }
}

Non-Local Returns Require inline

किसी function को पास किए lambda के अंदर एक साधारण return सिर्फ तभी अनुमति है जब वह function inline हो, क्योंकि inlining के बाद lambda का code खुद calling function का हिस्सा बन जाता है।

उदाहरण: Non-Local Returns Require inline

markup
inline fun findFirst(numbers: List<Int>, predicate: (Int) -> Boolean): Int? {
    // Loop over `numbers`, binding each item to `n`
    for (n in numbers) {
        if (predicate(n)) return n
    }
    // Return `null` from this function
    return null
}

// Entry point: execution of the program starts here
fun main() {
    // Declare a read-only variable `result`, set to `findFirst(listOf(1, 2, 3, 4)) { it > 2 }`
    val result = findFirst(listOf(1, 2, 3, 4)) { it > 2 }
    // Print "First match: $result" to the console, with a trailing newline
    println("First match: $result")
}

noinline and crossinline

noinline एक specific lambda parameter को inlining से बाहर चिह्नित करता है (अगर इसे store या कहीं और पास करना हो तो उपयोगी), जबकि crossinline किसी lambda को inline होने देता है लेकिन इसे non-local return करने से मना करता है।

उदाहरण: noinline and crossinline

markup
inline fun runTasks(crossinline first: () -> Unit, noinline second: () -> Unit) {
    // Declare a read-only variable `wrapped`, set to `Runnable { first() }`
    val wrapped = Runnable { first() }
    wrapped.run()
    second()
}

// Entry point: execution of the program starts here
fun main() {
    runTasks({ println("First task") }, { println("Second task") })
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. performance win की उम्मीद में किसी विशाल function को inline चिह्नित करना, जबकि बड़े functions को inline करना असल में बिना किसी मायने रखने वाले फायदे के compiled code को फुला सकता है।
  2. यह भूल जाना कि किसी lambda के अंदर non-local return सिर्फ इसलिए काम करता है क्योंकि उस lambda को accept करने वाला enclosing function inline है।
  3. ऐसे lambda parameters पर गलत तरीके से noinline या crossinline उपयोग करना जिन्हें उन खास behaviors की ज़रूरत नहीं।
चैप्टर सारांश
  • inline fun compiler को हर call site पर function के body (और इसके lambda parameters) को सीधे substitute करने के लिए कहता है।
  • Inlining function को पास किए हर lambda के लिए एक अलग object बनाने के runtime overhead से बचाता है।
  • किसी lambda से non-local returns सिर्फ इसलिए संभव हैं क्योंकि इसे पाने वाला function inlined है।
  • noinline किसी specific lambda parameter को inlining से मुक्त चिह्नित करता है, और crossinline किसी specific inlined lambda से non-local returns को मना करता है।
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.