Kotlin में Generics: क्यों ज़रूरी हैं और कैसे उपयोग करें

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Kotlin में Generics का परिचय



Generics (सामान्यीकरण) Kotlin भाषा की प्रमुख विशेषताओं में से एक है, जो लचीला, टाइप-सुरक्षित और पुन: प्रयोज्य कोड लिखने की अनुमति देता है। यदि आपने कभी List<String> या Map<Int, User> लिखा है, तो आपने बिना सोचे-समझे जेनेरिक का उपयोग किया है। लेकिन इन कोणीय कोष्ठकों के पीछे क्या है और उनसे अधिकतम लाभ कैसे उठाएं? इस लेख में, हम समझेंगे कि Kotlin में Generics की आवश्यकता क्यों है, उन्हें व्यवहार में कैसे लागू करें, और कौन सी उन्नत सुविधाएँ (variance, reified, where) आपको और भी स्वच्छ और सुरक्षित कोड लिखने में मदद करेंगी।



यह लेख उन डेवलपर्स के लिए है जो Kotlin की मूल बातों से पहले से परिचित हैं और अपने ज्ञान को गहरा करना चाहते हैं। हम मूल सिंटैक्स से लेकर production-कोड के वास्तविक उदाहरणों तक सब कुछ देखेंगे।



Generics की आवश्यकता क्यों? उनके बिना समस्या



कल्पना करें कि आपको एक फ़ंक्शन लिखना है जो किसी भी तत्वों की सूची लेता है और पहला तत्व लौटाता है। जेनेरिक के बिना, आप इस प्रकार लिखेंगे:



fun getFirst(list: List<Any>): Any {    return list[0]}


अब, यदि आप List<String> पास करते हैं, तो आउटपुट पर आपको Any मिलेगा। इसे स्ट्रिंग के रूप में उपयोग करने के लिए, आपको स्पष्ट टाइप कास्टिंग करनी होगी:



val first = getFirst(listOf("Kotlin", "Java")) as Stringfirst.length // खतरनाक! ClassCastException हो सकता है


यह असुविधाजनक और असुरक्षित है। त्रुटि केवल रनटाइम में दिखाई देगी। Generics इस समस्या को हल करते हैं, कंपाइलेशन के समय टाइप की जानकारी को संरक्षित करके।



Generics के मुख्य लाभ:

  • टाइप सुरक्षा — कंपाइलर रनटाइम के बजाय कंपाइलेशन के समय टाइप की जाँच करता है।
  • स्पष्ट कास्टिंग का उन्मूलन — कोड स्वच्छ और अधिक पठनीय हो जाता है।
  • पुन: प्रयोज्यता — एक क्लास या फ़ंक्शन विभिन्न प्रकारों के साथ काम करता है।


मूल सिंटैक्स: क्लासेज़, फ़ंक्शन और सीमाएँ



सामान्यीकृत क्लासेज़



शुरू करने का सबसे सरल तरीका एक या अधिक टाइप पैरामीटर वाली क्लास घोषित करना है। टाइप पैरामीटर कोणीय कोष्ठक <T> में निर्दिष्ट किए जाते हैं (अक्षर कोई भी हो सकता है, लेकिन पारंपरिक रूप से T, E, K, V का उपयोग किया जाता है):



class Box<T>(val value: T)

fun main() { val stringBox = Box("Kotlin") // टाइप स्वचालित रूप से निर्धारित होता है val intBox = Box(42) // Box<Int>

println(stringBox.value.length) // बिना कास्टिंग के काम करता है! println(intBox.value + 1) // 43}


Kotlin टाइप निर्धारित कर सकता है, इसलिए Box<String> लिखना आवश्यक नहीं है — Box("Kotlin") पर्याप्त है।



सामान्यीकृत फ़ंक्शन



फ़ंक्शन भी सामान्यीकृत हो सकते हैं। टाइप पैरामीटर फ़ंक्शन के नाम से पहले निर्दिष्ट किया जाता है:



fun <T> getMiddleElement(list: List<T>): T? {    if (list.isEmpty()) return null    return list[list.size / 2]}

fun main() { val numbers = listOf(1, 2, 3, 4, 5) val middle = getMiddleElement(numbers) // टाइप Int? स्वचालित रूप से निर्धारित होता है println(middle) // 3}


सीमाएँ (where / upper bound)



कभी-कभी यह सीमित करना आवश्यक होता है कि जेनेरिक में किन प्रकारों का उपयोग किया जा सकता है। उदाहरण के लिए, .compareTo() विधि को कॉल करने के लिए, टाइप को Comparable इंटरफ़ेस को लागू करना होगा:



fun <T : Comparable<T>> maxOfTwo(a: T, b: T): T {    return if (a >= b) a else b}

fun main() { println(maxOfTwo(10, 20)) // 20 println(maxOfTwo("A", "B")) // B // maxOfTwo(10, "A") // कंपाइलेशन त्रुटि: टाइप मेल नहीं खाते}


यदि कई सीमाओं की आवश्यकता है, तो where कीवर्ड का उपयोग करें:



interface Printable {    fun print()}

fun <T> process(item: T) where T : Comparable<T>, T : Printable

ब्लॉग

पुस्तक अनुशंसाएँ