परिचय: Kotlin आसान क्यों लगता है, लेकिन हैरान क्यों करता है
\n\nKotlin एक आधुनिक, संक्षिप्त और बेहद सुविधाजनक भाषा है। कई शुरुआती Java या Python से आते हैं और सोचते हैं: "यहाँ तो सब कुछ साफ़ है!"। और सच में, Kotlin का सिंटैक्स साफ़ है, nullable टाइप्स NPE से बचाते हैं, और let, apply, run जैसी फंक्शनल फीचर्स जादुई रूप से सरल लगती हैं। लेकिन यही दिखावटी सरलता अक्सर एक जाल बन जाती है।
इस लेख में हम Kotlin सीखने वालों की सबसे आम गलतियों पर चर्चा करेंगे। आप जानेंगे कि उनसे कैसे बचें और तैयार कोड उदाहरण प्राप्त करेंगे। अगर आप Kotlin सीखना शुरू कर रहे हैं, तो यह लेख आपको घंटों डिबगिंग से बचाएगा।
\n\nगलती #1: null safety को नज़रअंदाज़ करना या उससे डरना
\n\nKotlin ने null safety को सीधे टाइप सिस्टम में शामिल किया है। यह एक वरदान है, लेकिन शुरुआती अक्सर दो चरम सीमाओं में पड़ जाते हैं। पहली है पूरी तरह से अनदेखी करना और हर कदम पर !! (not-null assertion) ऑपरेटर का उपयोग करना। दूसरी है एल्विस ऑपरेटर ?: और ?.let की श्रृंखलाओं का अत्यधिक उपयोग, जो कोड को पढ़ने लायक नहीं छोड़ता।
गलती कैसी दिखती है
\n\n// बुरा: पूरी तरह !! — Kotlin की सुरक्षा को खत्म करता है\nfun processUser(user: User?) {\n val name = user!!.name // अगर user == null — क्रैश!\n println(name.uppercase())\n}\n\n// बुरा: बहुत ज़्यादा नेस्टेड let\nfun getUserCity(user: User?): String? {\n return user?.let {\n it.address?.let { addr ->\n addr.city?.let { city ->\n city.name\n }\n }\n }\n}\n\n\nसही तरीका
\n\n// अच्छा: सुरक्षित कॉल + एल्विस का उपयोग\nfun processUserSafe(user: User?) {\n val name = user?.name ?: "अतिथि"\n println(name.uppercase())\n}\n\n// बेहतरीन: बिना नेस्टिंग के एक्सटेंशन और स्कोप फंक्शन\nfun getUserCityClean(user: User?): String? {\n return user?.address?.city?.name\n}\n\n\nसुझाव: !! ऑपरेटर का उपयोग केवल तभी करें जब आप 100% आश्वस्त हों कि मान null नहीं है (जैसे if में जाँच के बाद)। बाकी मामलों में ?. और ?: का उपयोग करें।
यह Kotlin शुरुआती लोगों की मुख्य समस्याओं में से एक है — वे या तो null से डरते हैं, या समझ नहीं पाते कि इसके साथ कैसे काम करें। याद रखें: Kotlin null को मना नहीं करता, यह आपको इसके बारे में सोचने पर मजबूर करता है।
\n\nगलती #2: var, val और कॉन्स्टेंट के बीच अंतर न समझना
\n\nलगता है कि val एक फाइनल वेरिएबल है, जैसे Java में final। लेकिन ऐसा नहीं है। val एक read-only रेफरेंस है, न कि अपरिवर्तनीय ऑब्जेक्ट। शुरुआती अक्सर val को कंपाइल-टाइम कॉन्स्टेंट (const val) समझ लेते हैं और हैरान होते हैं कि उनका कोड सही से काम क्यों नहीं कर रहा।
भ्रम का उदाहरण
\n\n// शुरुआती सोचता है: "val = अपरिवर्तनीय"\nval list = mutableListOf(1, 2, 3)\nlist.add(4) // काम करता है! लेकिन शुरुआती हैरान\n\n// यह पहले से कंपाइल एरर है\nval name = "Alice"\nname = "Bob" // एरर: val को दोबारा असाइन नहीं किया जा सकता\n\n\nअंतर कैसे समझें
\n\n// कंपाइल-टाइम कॉन्स्टेंट — केवल प्रिमिटिव और String के लिए\nconst val PI = 3.14159\n\n// Read-only रेफरेंस — runtime में गणना की जा सकती है\nval currentTime = System.currentTimeMillis()\n\n// वास्तविक अपरिवर्तनीयता — immutable कलेक्शन का उपयोग करें\nval immutableList = listOf(1, 2, 3) // listOf, mutableListOf नहीं\n\n\nसुनहरा नियम: जहाँ संभव हो, val का उपयोग करें। अगर वेरिएबल को बदलना है, तभी var का उपयोग करें। और const val का उपयोग केवल टॉप-लेवल कॉन्स्टेंट या object/companion object के अंदर करें।
गलती #3: companion object और object-सिंगलटन का दुरुपयोग
\n\nKotlin ob