Kotlin में स्कोप फ़ंक्शंस पाँच मानक लाइब्रेरी फ़ंक्शन (let, run, with, apply, also) हैं जो किसी ऑब्जेक्ट के संदर्भ में कोड ब्लॉक निष्पादित करते हैं। ये ऑब्जेक्ट तक पहुँचने के तरीके (it या this के माध्यम से) और वापसी मान (संदर्भ ऑब्जेक्ट या lambda परिणाम) में भिन्न होते हैं। Kotlin दस्तावेज़ (2026) के अनुसार, सही स्कोप फ़ंक्शन का चयन बॉयलरप्लेट कोड को 25–40% तक कम करता है। स्कोप फ़ंक्शंस ऑब्जेक्ट आरंभीकरण, कॉन्फ़िगरेशन और रूपांतरण को घोषणात्मक शैली में लिखने में मदद करते हैं।
मुख्य बिंदु
स्कोप फ़ंक्शंस पाँच फ़ंक्शनों (let, run, with, apply, also) का एक सेट है जो Kotlin मानक लाइब्रेरी में निर्मित हैं। उनमें से प्रत्येक एक lambda लेता है और अस्थायी रूप से दायरा बदलता है ताकि lambda के अंदर कोड किसी विशिष्ट ऑब्जेक्ट के संदर्भ में निष्पादित हो। यह कई कॉलों में ऑब्जेक्ट नाम को दोहराने से बचाता है और संबंधित संचालन को एक ब्लॉक में समूहित करता है।
दो मुख्य विशेषताएँ स्कोप फ़ंक्शंस को अलग करती हैं: संदर्भ ऑब्जेक्ट तक पहुँचने का तरीका (this या it के माध्यम से) और वापसी मान (संदर्भ ऑब्जेक्ट स्वयं या lambda परिणाम)। this के माध्यम से पहुँच ऑब्जेक्ट को अंतर्निहित प्राप्तकर्ता बनाती है — विधियाँ और गुण बिना किसी उपसर्ग के कॉल किए जाते हैं। it के माध्यम से पहुँच ऑब्जेक्ट को lambda के स्पष्ट पैरामीटर के रूप में पास करती है। ऑब्जेक्ट लौटाने से श्रृंखलन संभव होता है, परिणाम लौटाने से रूपांतरित मान निर्दिष्ट किया जा सकता है।
ऐतिहासिक रूप से, स्कोप फ़ंक्शंस क्लासिक Builder पैटर्न और आरंभीकरण के लिए अस्थायी चर के प्रतिस्थापन के रूप में उभरे। एक अलग builder वर्ग बनाने के बजाय, डेवलपर apply { गुण1 = ...; गुण2 = ... } लिखता है। यह कोड की मात्रा को कम करता है और आरंभीकरण को अधिक पठनीय बनाता है। Kotlin पारिस्थितिकी तंत्र में, स्कोप फ़ंक्शंस का उपयोग सभी फ्रेमवर्क और लाइब्रेरी में एक मानक भाषा मुहावरे के रूप में किया जाता है।
सही स्कोप फ़ंक्शन का चयन दो प्रश्नों द्वारा निर्धारित होता है: क्या आप ऑब्जेक्ट तक पहुँचने के लिए this या it का उपयोग करना चाहते हैं, और क्या आप ऑब्जेक्ट स्वयं या lambda परिणाम लौटाना चाहते हैं। दो द्विआधारी विशेषताओं का संयोजन चार संभावित विकल्प देता है, और with एक विशेष स्थान रखता है जो एकमात्र ऐसा फ़ंक्शन है जो विस्तार नहीं है।
| फ़ंक्शन | पहुँच | वापसी | विस्तार? | विशिष्ट परिदृश्य |
|---|---|---|---|---|
| let | it | lambda परिणाम | हाँ | रूपांतरण, null-जाँच |
| run | this | lambda परिणाम | हाँ | संदर्भ के साथ गणना |
| with | this | lambda परिणाम | नहीं | कॉलों का समूहीकरण |
| apply | this | संदर्भ ऑब्जेक्ट | हाँ | गुणों का आरंभीकरण |
| also | it | संदर्भ ऑब्जेक्ट | हाँ | दुष्प्रभाव, लॉगिंग |
नया मान लौटाए बिना ऑब्जेक्ट कॉन्फ़िगर करने के लिए, apply (this के माध्यम से पहुँच) या also (it के माध्यम से पहुँच) का उपयोग करें। ऑब्जेक्ट के आधार पर नए मान की गणना करने के लिए, let (it के माध्यम से पहुँच) या run (this के माध्यम से पहुँच) का उपयोग करें। श्रृंखलन के बिना कॉलों को समूहीकृत करने के लिए, with का उपयोग करें। इस योजना का पालन करने से कोड Kotlin से परिचित अन्य डेवलपर्स के लिए पूर्वानुमेय हो जाता है।
apply एक स्कोप फ़ंक्शन है जो संदर्भ ऑब्जेक्ट लौटाता है और इसके माध्यम से this तक पहुँच प्रदान करता है। यह निर्माण के बाद ऑब्जेक्ट गुणों को आरंभ करने के लिए आदर्श उपकरण है। apply ब्लॉक के अंदर ऑब्जेक्ट नाम दोहराए बिना गुण सेट किए जा सकते हैं। विधि स्वयं ऑब्जेक्ट लौटाती है, जिससे apply को श्रृंखलाओं में एम्बेड किया जा सकता है या आरंभकों में उपयोग किया जा सकता है।
data class ServerConfig(
var host: String = "localhost",
var port: Int = 8080,
var useTls: Boolean = false
)
val config = ServerConfig().apply {
host = "api.example.com"
port = 443
useTls = true
}
लिस्टिंग में apply this के माध्यम से सीधे गुणों तक पहुँचकर ServerConfig कॉन्फ़िगर करता है (this हटा दिया गया है)। apply के बिना config.host = ..., config.port = ... लिखना पड़ता — एक ही चर के तीन दोहराए गए संदर्भ। ऑब्जेक्ट लौटाने से कॉन्फ़िगरेशन परिणाम को val config में संग्रहीत किया जा सकता है। also, apply के विपरीत, ऑब्जेक्ट को it के माध्यम से पास करता है और दुष्प्रभावों के लिए उपयुक्त है।
fun saveUser(user: User) {
validate(user).also { result ->
println("मान्यता परिणाम: $result")
}
val savedUser = user.also {
log("Saving user ${it.id}")
database.save(it)
}
}
उदाहरण में also लॉगिंग के लिए उपयोग किया गया है — मूल ऑब्जेक्ट लौटाते हुए, यह ऑब्जेक्ट को बदले बिना एक दुष्प्रभाव (संदेश आउटपुट) करता है। यह एक श्रृंखला है: validate(user) User लौटाता है, also परिणाम लॉग करता है और उपयोगकर्ता को आगे भेजता है। also संग्रह में तत्व जोड़ने या रूपांतरण श्रृंखला के बीच में डिबगिंग के लिए भी उपयोगी है।
let एक स्कोप फ़ंक्शन है जो lambda परिणाम लौटाता है और संदर्भ को it के माध्यम से पास करता है। यह null-सुरक्षित रूपांतरणों के लिए प्राथमिक फ़ंक्शन है: यदि ऑब्जेक्ट nullable है, तो ?.let { } संयोजन केवल गैर-शून्य मानों के लिए ब्लॉक निष्पादित करेगा। let का उपयोग अस्थायी चर के दायरे को सीमित करने और एक प्रकार से दूसरे प्रकार में map-जैसे रूपांतरणों के लिए भी किया जाता है।
fun findUser(id: Int): User?
val displayName = findUser(42)?.let { user ->
"${user.name} (${user.email})"
} ?: "Unknown user"
// संग्रह रूपांतरण के साथ let
val numbers = listOf("1", "2", "3")
val parsed = numbers.firstOrNull()?.let {
it.toIntOrNull()
} ?: 0
पहले उदाहरण में let को ?. के माध्यम से कॉल किया गया है — ब्लॉक केवल तभी निष्पादित होता है जब findUser ने गैर-शून्य लौटाया हो। Lambda it के माध्यम से user लेता है (स्पष्टता के लिए नाम बदला जा सकता है) और एक स्वरूपित स्ट्रिंग लौटाता है। यदि उपयोगकर्ता नहीं मिलता है, तो Elvis ऑपरेटर ?: डिफ़ॉल्ट मान देता है। दूसरे उदाहरण में let स्ट्रिंग को संभावित null के साथ संख्या में रूपांतरित करता है।
run this के माध्यम से पहुँच के साथ let का एनालॉग है, जो lambda परिणाम लौटाता है। run उन गणनाओं के लिए सुविधाजनक है जिनमें ऑब्जेक्ट संदर्भ की आवश्यकता होती है लेकिन नया मान लौटाती हैं। बिना ऑब्जेक्ट के run() कॉल करना (run { ... } के रूप में) चर के लिए एक अस्थायी दायरा बनाता है। with this के माध्यम से पहुँच वाला गैर-विस्तार है, जो श्रृंखलन के बिना कॉलों को समूहीकृत करने के लिए उपयुक्त है।
// संदर्भ-संचालित गणना के रूप में run
val transformed = listOf(1, 2, 3).run {
filter { it > 1 }.map { it * 10 }
}
println(transformed) // [20, 30]
// कॉलों को समूहीकृत करने के लिए with
val info = with(StringBuilder()) {
append("Name: ")
append("Alice")
toString()
}
उदाहरण में सूची पर run फ़िल्टरिंग और मैपिंग का परिणाम लौटाता है — स्वयं रूपांतरण, सूची नहीं। with StringBuilder को तर्क के रूप में लेता है (डॉट के माध्यम से नहीं) और अंदर this के साथ काम करता है: append, append, toString। with का परिणाम info स्ट्रिंग है। run और with के बीच चयन अक्सर व्यक्तिपरक होता है, लेकिन with तब बेहतर होता है जब ऑब्जेक्ट बिना श्रृंखलन के किसी अन्य स्थान से पास किया जाता है।
with अन्य स्कोप फ़ंक्शंस से इस मायने में भिन्न है कि यह एक विस्तार फ़ंक्शन नहीं है। यह ऑब्जेक्ट को पहले तर्क के रूप में और lambda को दूसरे तर्क के रूप में लेता है। lambda के अंदर ऑब्जेक्ट this के माध्यम से सुलभ है। with परिणाम सहेजे बिना ऑब्जेक्ट विधि कॉलों को समूहीकृत करने या जब कई गुणों को पढ़ने के लिए अस्थायी रूप से संदर्भ में “प्रवेश” करने की आवश्यकता होती है, तब सुविधाजनक है।
val user = User("Alice", "alice@example.com", "Admin")
val summary = with(user) {
"User $name has role $role and email $email"
}
println(summary)
// UI घटक आरंभीकरण के लिए with
with(TextView(context)) {
text = "Hello"
textSize = 18.0f
setTextColor(Color.BLUE)
}
पहले उदाहरण में with this के माध्यम से सीधे user गुणों तक पहुँचकर summary स्ट्रिंग बनाता है। with के बिना "User ${user.name} has role ${user.role}" लिखना पड़ता — user की बार-बार पुनरावृत्ति। दूसरे उदाहरण में with TextView कॉन्फ़िगरेशन को समूहीकृत करता है: सभी विधियाँ और गुण बिना दोहराव के एक ऑब्जेक्ट पर कॉल किए जाते हैं। with की कमी — श्रृंखला में उपयोग करने में असमर्थता, क्योंकि यह विस्तार नहीं है और संदर्भ ऑब्जेक्ट नहीं लौटाता है।
अक्सर पूछे जाने वाले प्रश्न
apply का उपयोग करें — यह ऑब्जेक्ट लौटाता है और this के माध्यम से पहुँच प्रदान करता है, जिससे ऑब्जेक्ट नाम दोहराए बिना गुण सेट किए जा सकते हैं। also उपयुक्त है यदि ऑब्जेक्ट गुणों से अंतर करने के लिए स्पष्ट it पैरामीटर की आवश्यकता हो।
let संदर्भ को it (स्पष्ट पैरामीटर) के माध्यम से पास करता है, run — this (अंतर्निहित प्राप्तकर्ता) के माध्यम से। let null-जाँच और रूपांतरण के लिए सुविधाजनक है, run — संदर्भ के साथ गणना के लिए। दोनों lambda परिणाम लौटाते हैं।
with विस्तार नहीं है — यह ऑब्जेक्ट को तर्क के रूप में लेता है। with का उपयोग कॉलों को समूहीकृत करने के लिए करें जब श्रृंखलन की आवश्यकता न हो। apply एक विस्तार है जो ऑब्जेक्ट लौटाता है, आरंभकों और builder पैटर्न में सुविधाजनक है।
हाँ, लेकिन this से सावधान रहें — नेस्टेड this भ्रम पैदा करता है। नेस्टेड संदर्भों के लिए स्पष्ट नामों के साथ let या also का उपयोग करें ताकि बाहरी ऑब्जेक्ट का संदर्भ देते समय अस्पष्टता से बचा जा सके।
सभी स्कोप फ़ंक्शंस inline हैं, इसलिए वे अनाम वर्गों से ओवरहेड नहीं बनाते हैं। उनके बीच प्रदर्शन अंतर नगण्य है। चयन पठनीयता और परंपराओं पर आधारित होना चाहिए, गति पर नहीं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें