Kotlin में इनलाइन फंक्शन: यह क्या है, सिंटैक्स और उपयोग

लेखक: IT Sectr प्रकाशित: 2026-06-21 पढ़ने का समय: 9 मिनट

इनलाइन फंक्शन — Kotlin तंत्र जिसमें फंक्शन का बॉडी संकलन समय पर सीधे प्रत्येक कॉल स्थान पर प्रतिस्थापित हो जाता है। यह लैम्ब्डा पैरामीटर के लिए अनाम क्लास और ऑब्जेक्ट बनाने के ओवरहेड को समाप्त करता है। Kotlin Documentation, 2025 के अनुसार, inline कीवर्ड उच्च-क्रम फंक्शन के लिए विशेष रूप से प्रभावी है, जहाँ प्रत्येक लैम्ब्डा इनलाइनिंग के बिना एक अलग FunctionN ऑब्जेक्ट बनाता है, जिससे गार्बेज कलेक्टर पर भार बढ़ता है।

मुख्य बिंदु

  • इनलाइन फंक्शन — फंक्शन जिसका बॉडी संकलन समय पर कॉल स्थान पर इनलाइन हो जाता है
  • ओवरहेड में कमी — लैम्ब्डा के लिए अनाम क्लास और ऑब्जेक्ट बनाने को समाप्त करता है
  • नॉनलोकल रिटर्न — इनलाइन फंक्शन के अंदर लैम्ब्डा बाहरी फंक्शन से return कर सकते हैं
  • noinline — विशिष्ट लैम्ब्डा पैरामीटर के इनलाइनिंग को रोकता है
  • crossinline — नॉनलोकल रिटर्न की अनुमति देता है लेकिन इनलाइन फंक्शन संदर्भ से return को रोकता है

Kotlin में इनलाइन फंक्शन क्या है?

इनलाइन फंक्शन एक फंक्शन है जो inline कीवर्ड से चिह्नित होता है। Kotlin संकलक इसके लिए अलग बाइटकोड नहीं बनाता — बल्कि फंक्शन के बॉडी को सीधे प्रत्येक कॉल स्थान पर कॉपी करता है। मुख्य उद्देश्य उच्च-क्रम फंक्शन को ऑप्टिमाइज़ करना है जो लैम्ब्डा एक्सप्रेशन स्वीकार करते हैं, क्योंकि सामान्य स्थिति में प्रत्येक लैम्ब्डा एक अनाम Function क्लास ऑब्जेक्ट बनाता है।

JetBrains Tech Blog (2024) के अनुसार, Kotlin में इनलाइन फंक्शन का उपयोग उन फंक्शन में बनाए गए ऑब्जेक्ट की संख्या को 40–60% तक कम कर सकता है जो लैम्ब्डा का गहन उपयोग करते हैं। लूप और उच्च-लोड संचालन (सॉर्टिंग, कलेक्शन फ़िल्टरिंग) में यह मापने योग्य प्रदर्शन लाभ प्रदान करता है।

Inline के बिना, प्रत्येक लैम्ब्डा एक अनाम क्लास (या संश्लेषित कार्यात्मक इंटरफ़ेस के इंस्टेंस) में संकलित होता है। वेरिएबल कैप्चर करने वाले लैम्ब्डा के लिए, अतिरिक्त रैपर ऑब्जेक्ट बनाए जाते हैं। इनलाइन फंक्शन संकलन समय पर इन सभी ऑब्जेक्ट को समाप्त कर देते हैं, उन्हें बिना रैपर के स्थानीय वेरिएबल तक पहुँचने वाले सीधे कोड से बदल देते हैं।

Inline का उपयोग केवल लैम्ब्डा पैरामीटर वाले फंक्शन के लिए करें — Kotlin संकलक स्वयं चेतावनी देता है यदि inline कोई लाभ प्रदान नहीं करता है।

इनलाइन फंक्शन का सिंटैक्स और यह कैसे काम करता है

बस फंक्शन घोषणा से पहले inline कीवर्ड जोड़ें। संकलक स्वचालित रूप से कॉल स्थानों पर फंक्शन बॉडी को प्रतिस्थापित करता है। फंक्शन स्वयं बाइटकोड में उन मामलों के लिए मौजूद रहता है जब इसे सीधे नहीं बुलाया जाता (उदाहरण के लिए, Java कोड से)।

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

// कॉल — लैम्ब्डा कोड फंक्शन बॉडी में इनलाइन हो जाता है
5.repeatAction { index ->
    println("Index: $index")
}

संकलन के बाद, उपरोक्त कोड इसके बराबर होगा:

kotlin
// इनलाइनिंग के बाद क्या होता है (योजनाबद्ध रूप से):
val $this = 5
for (i in 0 until $this) {
    println("Index: $i")
}

लैम्ब्डा के लिए कोई ऑब्जेक्ट नहीं बनाया जाता — एक्शन कोड सीधे निष्पादित होता है। यही ऑप्टिमाइज़ेशन का सार है: Function.invoke() को कॉल करने के बजाय — लैम्ब्डा बॉडी के साथ कोड का सीधा सम्मिलन।

डीकंपाइलेशन के माध्यम से सत्यापन

इनलाइनिंग को सत्यापित करने के लिए, IntelliJ IDEA में Tools > Kotlin > Show Kotlin Bytecode खोलें और Decompile पर क्लिक करें। आप देखेंगे कि लैम्ब्डा के साथ repeatAction को कॉल करने के बजाय, for लूप के साथ फंक्शन बॉडी का सीधा सम्मिलन उत्पन्न होता है।

लैम्ब्डा ओवरहेड की समस्या और इसका समाधान

Kotlin में प्रत्येक लैम्ब्डा तीन वेरिएंट में से एक में संकलित होता है। पहला — यदि लैम्ब्डा वेरिएबल कैप्चर नहीं करता, तो यह उस क्लास की स्थैतिक विधि बन जाता है जहाँ इसे घोषित किया गया है। दूसरा — यदि यह एक वेरिएबल कैप्चर करता है, तो एक अनाम क्लास बनाई जाती है। तीसरा — यदि यह कई वेरिएबल कैप्चर करता है, तो प्रत्येक कैप्चर किए गए वेरिएबल के लिए फ़ील्ड वाली एक अनाम क्लास बनाई जाती है।

लैम्ब्डा प्रकारInline के बिनाInline के साथ
बिना कैप्चरएक स्थैतिक विधि (पुनः उपयोग)पूर्ण इनलाइनिंग, बिना कॉल
1 वेरिएबल कैप्चरअनाम क्लास (एक ऑब्जेक्ट)पूर्ण इनलाइनिंग, बिना ऑब्जेक्ट
N वेरिएबल कैप्चरN फ़ील्ड वाली अनाम क्लासपूर्ण इनलाइनिंग, बिना ऑब्जेक्ट
पुनरावर्तीसामान्य कॉलinline निषिद्ध

Android Performance Patterns (Google, 2024) के अनुसार, कलेक्शन के गहन उपयोग वाले एप्लिकेशन (फ़िल्टरिंग, सॉर्टिंग, ग्रुपिंग) में इनलाइन फंक्शन आवंटन को 25–35% तक कम करते हैं। प्रभाव विशेष रूप से Jetpack Compose में ध्यान देने योग्य है, जहाँ प्रत्येक स्थिति परिवर्तन कई लैम्ब्डा के साथ पुनर्संरचना को ट्रिगर करता है।

नॉनलोकल रिटर्न और सीमाएँ

सामान्य फंक्शन में लैम्ब्डा बाहरी फंक्शन से return नहीं कर सकता — केवल लैम्ब्डा से स्थानीय return (return@label के माध्यम से)। इनलाइन फंक्शन में, लैम्ब्डा कॉल करने वाले फंक्शन के बॉडी में इनलाइन हो जाता है, इसलिए नॉनलोकल रिटर्न संभव हो जाता है: लैम्ब्डा के अंदर return बाहरी फंक्शन को समाप्त कर देता है।

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 }
    // लैम्ब्डा में return processNumbers() से null लौटाएगा
}

नॉनलोकल रिटर्न शीघ्र समाप्ति के लिए सुविधाजनक है, लेकिन त्रुटियों का कारण बन सकता है। यदि लैम्ब्डा का उपयोग गैर-स्थानीय संदर्भ में किया जाता है (एक वेरिएबल में संग्रहीत), तो नॉनलोकल रिटर्न RuntimeException का कारण बनेगा। Kotlin संकलक ऐसे भंडारण का प्रयास करने पर चेतावनी जारी करता है।

noinline और crossinline: इनलाइनिंग को नियंत्रित करना

जब किसी फंक्शन में कई लैम्ब्डा पैरामीटर होते हैं, तो कभी-कभी केवल उनमें से कुछ को इनलाइन करने की आवश्यकता होती है। इसके लिए noinline का उपयोग किया जाता है — यह किसी विशिष्ट लैम्ब्डा पैरामीटर के इनलाइनिंग को रोकता है, इसे सामान्य Function ऑब्जेक्ट के रूप में छोड़ता है।

crossinline मॉडिफ़ायर विपरीत समस्या हल करता है: लैम्ब्डा इनलाइन होता है, लेकिन नॉनलोकल रिटर्न निषिद्ध होता है। यह तब आवश्यक है जब लैम्ब्डा का उपयोग किसी अन्य लैम्ब्डा के अंदर या ऐसे संदर्भ में किया जाता है जहाँ return की अनुमति नहीं है (उदाहरण के लिए, Runnable को पास किया गया)।

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 को वेरिएबल में संग्रहीत या कहीं और पास किया जा सकता है
val errorHandler = { e: Exception -> log(e.message) }
processWithCallback("input", { println(it) }, errorHandler)

उदाहरण में, onSuccess को crossinline के रूप में चिह्नित किया गया है — यह इनलाइन होगा, लेकिन इसके अंदर return का उपयोग नहीं किया जा सकता। onError को noinline के रूप में चिह्नित किया गया है — यह इनलाइन नहीं होता, इसलिए इसे ऑब्जेक्ट के रूप में पास किया जा सकता है, क्लास फ़ील्ड में संग्रहीत किया जा सकता है, या लिसनर के रूप में उपयोग किया जा सकता है।

इनलाइन फंक्शन की सीमाएँ और सुझाव

इनलाइन फंक्शन की सीमाएँ हैं। पुनरावर्ती इनलाइन फंक्शन निषिद्ध हैं — संकलक त्रुटि लौटाएगा। इनलाइन फंक्शन में private या internal दृश्यता नहीं हो सकती यदि वे किसी अन्य मॉड्यूल में घोषित किए गए हैं, लेकिन यह दृश्यता सीमा है, इनलाइनिंग तंत्र से संबंधित नहीं।

प्रत्येक इनलाइन फंक्शन कॉल के साथ बाइटकोड आकार बढ़ता है, क्योंकि बॉडी कॉपी की जाती है। Kotlin Coding Conventions (JetBrains, 2025) के अनुसार, inline का उपयोग केवल 10–15 पंक्तियों तक के फंक्शन के लिए करने की अनुशंसा की जाती है। बड़े फंक्शन के लिए, लैम्ब्डा इनलाइनिंग का लाभ APK आकार में वृद्धि से नकारा जा सकता है (Android में 64K विधि सीमा के कारण महत्वपूर्ण)।

kotlin
// अनुशंसित अभ्यास
inline fun withLock(lock: Lock, action: () -> T): T {
    lock.lock()
    try {
        return action()
    } finally {
        lock.unlock()
    }
}

// बड़े फंक्शन के लिए अनुशंसित नहीं
inline fun largeComputation(...) { // खराब — बॉडी >50 पंक्तियाँ
    // 50 पंक्तियों से अधिक — सामान्य फंक्शन में निकालना बेहतर
}

लाइब्रेरी में सार्वजनिक इनलाइन फंक्शन को सावधानी की आवश्यकता है: यदि इनलाइन फंक्शन का बॉडी बदलता है, तो सभी क्लाइंट को पुनर्संकलित करना होगा। JetBrains एक मॉड्यूल के भीतर संगतता बनाए रखने के लिए इनलाइन फंक्शन से कॉल किए जाने वाले सदस्यों के लिए @PublishedApi internal का उपयोग करने की अनुशंसा करता है।

अक्सर पूछे जाने वाले प्रश्न

क्या इनलाइन एक्सटेंशन फंक्शन बनाया जा सकता है?

हाँ, इनलाइन एक्सटेंशन फंक्शन बिना किसी प्रतिबंध के काम करता है। उदाहरण: inline fun String.transform(block: (Char) -> Char): String। एक्सटेंशन इनलाइन करने की क्षमता को प्रभावित नहीं करता — संकलक इसे सामान्य इनलाइन फंक्शन की तरह ही संभालता है।

Inline कब लाभ प्रदान नहीं करता?

यदि फंक्शन लैम्ब्डा पैरामीटर स्वीकार नहीं करता — inline कोई लाभ प्रदान नहीं करता। Kotlin संकलक चेतावनी जारी करता है: “Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types.” साथ ही, बाइटकोड वृद्धि के कारण inline बड़े फंक्शन के लिए हानिकारक है।

Inline, @JvmInline (value class) से कैसे भिन्न है?

inline — एक फंक्शन मॉडिफ़ायर जो फंक्शन बॉडी को कॉल स्थान पर इनलाइन करता है। @JvmInline (value class) — रैपर क्लास के लिए तंत्र जो संकलन समय पर उनके मान से बदल दिए जाते हैं। अलग अवधारणाएँ: inline कॉल को ऑप्टिमाइज़ करता है, value class डेटा प्रतिनिधित्व को ऑप्टिमाइज़ करता है।

क्या inline का उपयोग suspend फंक्शन के साथ किया जा सकता है?

नहीं, suspend फंक्शन inline नहीं हो सकते क्योंकि वे Continuation के साथ स्टेट मशीन में संकलित होते हैं। हालांकि, एक इनलाइन फंक्शन crossinline के साथ पैरामीटर के रूप में suspend लैम्ब्डा स्वीकार कर सकता है। इसका उपयोग अक्सर कोरूटीन में किया जाता है: inline fun launch(block: suspend CoroutineScope.() -> Unit).

क्या inline डीबगिंग को प्रभावित करता है?

हाँ, इनलाइन फंक्शन डीबगिंग को जटिल बनाते हैं क्योंकि फंक्शन बॉडी को कॉल नहीं किया जाता बल्कि कॉल स्थान पर इनलाइन किया जाता है। स्टैकट्रेस लंबे हो जाते हैं, ब्रेकपॉइंट काम करते हैं लेकिन अप्रत्याशित स्थान दिखा सकते हैं। JetBrains बिना inline के डीबग करने और केवल release बिल्ड में इसे सक्षम करने की अनुशंसा करता है।

सारांश

  • इनलाइन फंक्शन — फंक्शन बॉडी को कॉल स्थान पर इनलाइन करता है, लैम्ब्डा ओवरहेड को समाप्त करता है
  • नॉनलोकल रिटर्न — लैम्ब्डा से return बाहरी फंक्शन को समाप्त करता है (केवल inline के साथ संभव)
  • noinline — विशिष्ट लैम्ब्डा पैरामीटर के इनलाइनिंग को रोकता है
  • crossinline — इनलाइनिंग की अनुमति देता है लेकिन नॉनलोकल रिटर्न को रोकता है
  • पुनरावर्ती फंक्शन inline नहीं हो सकते — संकलक त्रुटि लौटाता है
  • बाइटकोड आकार बढ़ता है — 10–15 पंक्तियों तक के फंक्शन के लिए inline का उपयोग करें
  • इष्टतम उपयोग — लैम्ब्डा पैरामीटर वाले उच्च-क्रम फंक्शन, सिंक्रनाइज़ेशन ब्लॉक, स्कोप फंक्शन (let, apply, also, run)

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें