Kotlin: run, let, apply, also, with — कब क्या उपयोग करें? उदाहरणों के साथ पूर्ण विश्लेषण
\n\nनमस्ते दोस्त! यदि आप Kotlin सीख रहे हैं और स्वच्छ, संक्षिप्त कोड लिखना चाहते हैं, तो देर-सबेर आप पाँच जादुई फ़ंक्शनों से रूबरू होंगे: run, let, apply, also और with। ये scope functions (दायरा फ़ंक्शन) हैं — ये आपको किसी ऑब्जेक्ट के संदर्भ में कोड निष्पादित करने की अनुमति देते हैं और जीवन को बहुत आसान बनाते हैं।
लेकिन एक समस्या है: कई शुरुआती (और केवल वे ही नहीं) भ्रमित हो जाते हैं कि कब क्या उपयोग करना है। यह प्रश्न Stack Overflow पर सबसे लोकप्रिय में से एक है, और आज हम हमेशा के लिए समझ लेंगे कि गलती कैसे न करें। हम केवल नियमों को सूचीबद्ध नहीं करेंगे — हम अभ्यास से वास्तविक उदाहरण दिखाएंगे जिन्हें आप तुरंत अपनी परियोजनाओं में उपयोग कर सकते हैं।
\n\nscope functions क्या हैं और इनकी आवश्यकता क्यों है?
\nScope functions वे फ़ंक्शन हैं जो किसी ऑब्जेक्ट के लिए एक अस्थायी दायरा बनाते हैं। इस दायरे के अंदर, आप it या this के माध्यम से ऑब्जेक्ट तक पहुँच सकते हैं। उनके बीच मुख्य अंतर यह है कि वे परिणाम कैसे लौटाते हैं और वे संदर्भ को कैसे संदर्भित करते हैं।
यहाँ एक संक्षिप्त चीट शीट है, जिसे हम उदाहरणों से भरेंगे:
\n- \n
let— संदर्भ:it, लौटाता है: लैम्ब्डा का परिणाम। शून्य जाँच और कॉल श्रृंखलाओं के लिए उपयोग किया जाता है। \n run— संदर्भ:this, लौटाता है: लैम्ब्डा का परिणाम। सार्वभौमिक फ़ंक्शन, अक्सर आरंभीकरण और गणना के लिए। \n apply— संदर्भ:this, लौटाता है: स्वयं ऑब्जेक्ट। ऑब्जेक्ट के गुणों को कॉन्फ़िगर करने के लिए आदर्श। \n also— संदर्भ:it, लौटाता है: स्वयं ऑब्जेक्ट। अतिरिक्त क्रियाओं (लॉगिंग, जाँच) के लिए अच्छा है। \n with— extension फ़ंक्शन नहीं, संदर्भ:this, लौटाता है: लैम्ब्डा का परिणाम। नया ऑब्जेक्ट बनाए बिना एक ही ऑब्जेक्ट के कॉल को समूहित करने के लिए सुविधाजनक। \n
मुख्य नियम याद रखें: फ़ंक्शन का चुनाव इस बात पर निर्भर करता है कि आपको क्या चाहिए — ऑब्जेक्ट लौटाना है या परिणाम, और आप संदर्भ तक कैसे पहुँचना चाहते हैं (it या this के माध्यम से)।
1. let — सुरक्षित श्रृंखलाओं का राजा
\nlet आपका सबसे अच्छा दोस्त है जब nullable ऑब्जेक्ट्स के साथ काम करना हो। यह कोड केवल तभी निष्पादित करता है जब ऑब्जेक्ट null न हो। संदर्भ it के रूप में पारित किया जाता है।
उदाहरण: सुरक्षित रूपांतरण
\nval name: String? = "आंद्रेई"\n// let के बिना:\nif (name != null) {\n println("नाम की लंबाई: ${name.length}")\n}\n\n// let के साथ (अधिक सुरुचिपूर्ण):\nname?.let {\n println("नाम की लंबाई: ${it.length}")\n}\n\n\nlet संचालन की श्रृंखलाओं के लिए भी उपयुक्त है। उदाहरण के लिए, जब एक ऑब्जेक्ट को दूसरे में बदलना हो:
val numbers = listOf(1, 2, null, 4, null, 6)\nval nonNullSquared = numbers\n .mapNotNull { it }\n .let { list ->\n list.map { it * it }\n }\nprintln(nonNullSquared) // [1, 4, 16, 36]\n\n\nlet का उपयोग कब करें:
- \n
- null जाँच (सबसे सामान्य मामला)। \n
- एक मान को दूसरे में बदलना। \n
- परिणाम के साथ संचालन की श्रृंखला निष्पादित करना। \n
2. apply — बिना अनावश्यक शब्दों के कंस्ट्रक्टर
\napply स्वयं ऑब्जेक्ट लौटाता है, और लैम्ब्डा के अंदर संदर्भ this है। यह उपयोग से पहले ऑब्जेक्ट को कॉन्फ़िगर करने के लिए एक आदर्श उपकरण है। लंबे set ब्लॉक को भूल जाइए!
उदाहरण: View (Android) या data class को कॉन्फ़िगर करना
\ndata class User(var name: String = "", var age: Int = 0)\n\nval user = User().apply {\n name = "मारिया"\n age = 25\n}\nprintln(user) // User(name=मारिया, age=25)\n\n// और भी बढ़िया — TextView को कॉन्फ़िगर करना:\nval textView = TextView(context).apply {\n text = "नमस्ते, Kotlin!"\n textSize = 18f\n setTextCo