प्रोग्रामर के लिए Kotlin Bootcamp 5.1: एक्सटेंशन

यह कोडलैब, प्रोग्रामर के लिए Kotlin बूटकैंप कोर्स का हिस्सा है. अगर कोडलैब को क्रम से पूरा किया जाता है, तो आपको इस कोर्स से सबसे ज़्यादा फ़ायदा मिलेगा. अपनी जानकारी के हिसाब से, कुछ सेक्शन को सरसरी तौर पर पढ़ा जा सकता है. यह कोर्स उन प्रोग्रामर के लिए है जिन्हें ऑब्जेक्ट ओरिएंटेड लैंग्वेज के बारे में जानकारी है और जो Kotlin सीखना चाहते हैं.

परिचय

इस कोडलैब में, आपको Kotlin की कई अलग-अलग और काम की सुविधाओं के बारे में बताया गया है. इनमें पेयर, कलेक्शन, और एक्सटेंशन फ़ंक्शन शामिल हैं.

इस कोर्स में, एक सैंपल ऐप्लिकेशन बनाने के बजाय, अलग-अलग विषयों पर जानकारी दी गई है. हालांकि, ये विषय एक-दूसरे से जुड़े हुए हैं, लेकिन इन्हें इस तरह से डिज़ाइन किया गया है कि आप अपनी ज़रूरत के हिसाब से किसी भी विषय को पढ़ सकें. इन सभी उदाहरणों को एक साथ दिखाने के लिए, इनमें ऐक्वेरियम की थीम का इस्तेमाल किया गया है. अगर आपको एक्वेरियम की पूरी कहानी देखनी है, तो Udacity पर प्रोग्रामर के लिए Kotlin बूटकैंप कोर्स देखें.

आपको पहले से क्या पता होना चाहिए

  • Kotlin के फ़ंक्शन, क्लास, और तरीकों का सिंटैक्स
  • IntelliJ IDEA में Kotlin के REPL (Read-Eval-Print Loop) का इस्तेमाल करने का तरीका
  • IntelliJ IDEA में नई क्लास बनाने और प्रोग्राम चलाने का तरीका

आपको क्या सीखने को मिलेगा

  • जोड़ों और तीन के ग्रुप के साथ काम करने का तरीका
  • कलेक्शन के बारे में ज़्यादा जानकारी
  • स्थिरांकों को तय करना और उनका इस्तेमाल करना
  • एक्सटेंशन फ़ंक्शन लिखना

आपको क्या करना होगा

  • REPL में पेयर, ट्रिपल, और हैश मैप के बारे में जानें
  • कॉन्स्टेंट को व्यवस्थित करने के अलग-अलग तरीके जानें
  • एक्सटेंशन फ़ंक्शन और एक्सटेंशन प्रॉपर्टी लिखना

इस टास्क में, आपको पेयर और ट्रिपल के बारे में जानकारी मिलेगी. साथ ही, उन्हें डिस्ट्रक्चर करने का तरीका भी बताया जाएगा. पेयर और ट्रिपल, दो या तीन सामान्य आइटम के लिए पहले से बनी डेटा क्लास होती हैं. उदाहरण के लिए, इसका इस्तेमाल किसी फ़ंक्शन से एक से ज़्यादा वैल्यू पाने के लिए किया जा सकता है.

मान लें कि आपके पास List मछलियां हैं और isFreshWater() एक फ़ंक्शन है. इस फ़ंक्शन का इस्तेमाल यह पता लगाने के लिए किया जाता है कि मछली मीठे पानी की है या खारे पानी की. List.partition() दो सूचियां दिखाता है. एक में वे आइटम होते हैं जिनके लिए शर्त true है और दूसरी में वे आइटम होते हैं जिनके लिए शर्त false है.

val twoLists = fish.partition { isFreshWater(it) }
println("freshwater: ${twoLists.first}")
println("saltwater: ${twoLists.second}")

पहला चरण: कुछ जोड़े और तीन-तीन के ग्रुप बनाना

  1. REPL खोलें (टूल > Kotlin > Kotlin REPL).
  2. एक जोड़ी बनाएं. इसमें, किसी उपकरण को उसके इस्तेमाल के मकसद से जोड़ें. इसके बाद, वैल्यू प्रिंट करें. to कीवर्ड का इस्तेमाल करके, दो वैल्यू (जैसे, दो स्ट्रिंग) को जोड़ने वाला एक्सप्रेशन बनाकर एक पेयर बनाया जा सकता है. इसके बाद, हर वैल्यू को रेफ़र करने के लिए .first या .second का इस्तेमाल किया जा सकता है.
val equipment = "fish net" to "catching fish"
println("${equipment.first} used for ${equipment.second}")
⇒ fish net used for catching fish
  1. ट्रिपल बनाएं और उसे toString() की मदद से प्रिंट करें. इसके बाद, उसे toList() की मदद से सूची में बदलें. तीन वैल्यू के साथ Triple() का इस्तेमाल करके, एक ट्रिपल बनाया जाता है. हर वैल्यू को रेफ़र करने के लिए, .first, .second, और .third का इस्तेमाल करें.
val numbers = Triple(6, 9, 42)
println(numbers.toString())
println(numbers.toList())
⇒ (6, 9, 42)
[6, 9, 42]

ऊपर दिए गए उदाहरणों में, पेयर या ट्रिपल के सभी हिस्सों के लिए एक ही टाइप का इस्तेमाल किया गया है. हालांकि, ऐसा करना ज़रूरी नहीं है. ये हिस्से, स्ट्रिंग, संख्या या सूची हो सकते हैं. उदाहरण के लिए, कोई दूसरा पेयर या ट्रिपल.

  1. एक ऐसा पेयर बनाएं जिसमें पेयर का पहला हिस्सा खुद एक पेयर हो.
val equipment2 = ("fish net" to "catching fish") to "equipment"
println("${equipment2.first} is ${equipment2.second}\n")
println("${equipment2.first.second}")
⇒ (fish net, catching fish) is equipment
⇒ catching fish

दूसरा चरण: कुछ जोड़े और तीन वैल्यू वाले ऑब्जेक्ट को डीस्ट्रक्चर करना

जोड़ों और तीन संख्याओं को अलग-अलग हिस्सों में बांटने को डीस्ट्रक्चरिंग कहते हैं. पेयर या ट्रिपल को वैरिएबल की सही संख्या असाइन करें. इसके बाद, Kotlin हर हिस्से की वैल्यू को क्रम से असाइन करेगा.

  1. किसी पेयर को डिस्ट्रक्चर करें और वैल्यू प्रिंट करें.
val equipment = "fish net" to "catching fish"
val (tool, use) = equipment
println("$tool is used for $use")
⇒ fish net is used for catching fish
  1. ट्रिपल को डिस्ट्रक्चर करें और वैल्यू प्रिंट करें.
val numbers = Triple(6, 9, 42)
val (n1, n2, n3) = numbers
println("$n1 $n2 $n3")
⇒ 6 9 42

ध्यान दें कि पेयर और ट्रिपल को डिस्ट्रक्चर करने का तरीका, डेटा क्लास के डिस्ट्रक्चर करने के तरीके जैसा ही होता है. इसके बारे में पिछले कोडलैब में बताया गया था.

इस टास्क में, आपको कलेक्शन के बारे में ज़्यादा जानकारी मिलेगी. इसमें सूचियां और हैश मैप नाम का नया कलेक्शन टाइप शामिल है.

पहला चरण: सूचियों के बारे में ज़्यादा जानें

  1. पिछले लेसन में, लिस्ट और बदली जा सकने वाली लिस्ट के बारे में बताया गया था. ये बहुत काम के डेटा स्ट्रक्चर होते हैं. इसलिए, Kotlin में सूचियों के लिए कई बिल्ट-इन फ़ंक्शन उपलब्ध होते हैं. सूचियों के लिए, फ़ंक्शन की इस आंशिक सूची को देखें. आपको List और MutableList के लिए, Kotlin के दस्तावेज़ में पूरी लिस्ट मिल सकती है.

सुविधा

मकसद

add(element: E)

बदली जा सकने वाली सूची में कोई आइटम जोड़ें.

remove(element: E)

बदली जा सकने वाली सूची से कोई आइटम हटाएं.

reversed()

सूची की एक कॉपी लौटाता है, जिसमें एलिमेंट उल्टे क्रम में होते हैं.

contains(element: E)

अगर सूची में आइटम मौजूद है, तो true दिखाता है.

subList(fromIndex: Int, toIndex: Int)

सूची का वह हिस्सा दिखाएं जो पहले इंडेक्स से शुरू होता है और दूसरे इंडेक्स से पहले खत्म होता है.

  1. REPL में काम करते समय, संख्याओं की एक सूची बनाएं और उस पर sum() को कॉल करें. इसमें सभी एलिमेंट की जानकारी शामिल होती है.
val list = listOf(1, 5, 3, 4)
println(list.sum())
⇒ 13
  1. स्ट्रिंग की सूची बनाएं और सूची में मौजूद संख्याओं का योग करें.
val list2 = listOf("a", "bbb", "cc")
println(list2.sum())
⇒ error: none of the following functions can be called with the arguments supplied:
  1. अगर एलिमेंट ऐसी कोई चीज़ नहीं है जिसे List सीधे तौर पर जोड़ सकता है, जैसे कि कोई स्ट्रिंग, तो List के साथ लैम्डा फ़ंक्शन का इस्तेमाल करके, यह तय किया जा सकता है कि इसे कैसे जोड़ा जाए. उदाहरण के लिए, हर स्ट्रिंग की लंबाई के हिसाब से जोड़ने के लिए..sumBy() लैम्डा आर्ग्युमेंट का डिफ़ॉल्ट नाम it होता है. यहां it का मतलब सूची के हर एलिमेंट से है, क्योंकि सूची को ट्रैवर्स किया जाता है.
val list2 = listOf("a", "bbb", "cc")
println(list2.sumBy { it.length })
⇒ 6
  1. सूचियों की मदद से और भी बहुत कुछ किया जा सकता है. उपलब्ध फ़ंक्शन देखने का एक तरीका यह है कि IntelliJ IDEA में एक सूची बनाएं, उसमें डॉट जोड़ें, और फिर टूलटिप में अपने-आप पूरा होने वाली सूची देखें. यह किसी भी ऑब्जेक्ट के लिए काम करता है. इसे किसी सूची के साथ आज़माएं.

  1. सूची से listIterator() चुनें. इसके बाद, listIterator() स्टेटमेंट वाली सूची देखें और स्पेस से अलग किए गए सभी एलिमेंट प्रिंट करें.for
val list2 = listOf("a", "bbb", "cc")
for (s in list2.listIterator()) {
    println("$s ")
}
⇒ a bbb cc

दूसरा चरण: हैश मैप आज़माएं

Kotlin में, hashMapOf() का इस्तेमाल करके किसी भी चीज़ को किसी दूसरी चीज़ से मैप किया जा सकता है. हैश मैप, पेयर की सूची की तरह होते हैं. इनमें पहली वैल्यू, कुंजी के तौर पर काम करती है.

  1. एक हैश मैप बनाएं, जिसमें मछलियों के लक्षणों को कुंजियों के तौर पर और बीमारियों को वैल्यू के तौर पर दिखाया गया हो.
val cures = hashMapOf("white spots" to "Ich", "red sores" to "hole disease")
  1. इसके बाद, लक्षण की कुंजी के आधार पर बीमारी की वैल्यू को वापस पाया जा सकता है. इसके लिए, get() या इससे भी छोटे स्क्वेयर ब्रैकेट [] का इस्तेमाल करें.
println(cures.get("white spots"))
⇒ Ich
println(cures["red sores"])
⇒ hole disease
  1. मैप में मौजूद किसी लक्षण के बारे में जानकारी देने की कोशिश करें.
println(cures["scale loss"])
⇒ null

अगर कोई कुंजी मैप में नहीं है, तो उससे मिलती-जुलती बीमारी की जानकारी वापस पाने की कोशिश करने पर null मिलता है. मैप डेटा के आधार पर, ऐसा हो सकता है कि किसी संभावित कुंजी के लिए कोई मैच न मिले. ऐसे मामलों के लिए, Kotlin getOrDefault() फ़ंक्शन उपलब्ध कराता है.

  1. getOrDefault() का इस्तेमाल करके, ऐसी कुंजी ढूंढने की कोशिश करें जो किसी से मेल नहीं खाती.
println(cures.getOrDefault("bloating", "sorry, I don't know"))
⇒ sorry, I don't know

अगर आपको सिर्फ़ वैल्यू नहीं दिखानी है, तो Kotlin में getOrElse() फ़ंक्शन का इस्तेमाल करें.

  1. अपने कोड में बदलाव करके, getOrDefault() के बजाय getOrElse() का इस्तेमाल करें.
println(cures.getOrElse("bloating") {"No cure for this"})
⇒ No cure for this

डिफ़ॉल्ट वैल्यू दिखाने के बजाय, कर्ली ब्रैकेट {} के बीच मौजूद कोड को लागू किया जाता है. उदाहरण में, else सिर्फ़ एक स्ट्रिंग दिखाता है. हालांकि, यह किसी बीमारी का इलाज बताने वाले वेबपेज को ढूंढकर उसे दिखाने जैसा मुश्किल काम भी कर सकता है.

mutableListOf की तरह, mutableMapOf भी बनाई जा सकती है. बदले जा सकने वाले मैप में आइटम जोड़े और हटाए जा सकते हैं. बदले जा सकने वाले वैरिएबल का मतलब है कि उनकी वैल्यू बदली जा सकती है. वहीं, नहीं बदले जा सकने वाले वैरिएबल का मतलब है कि उनकी वैल्यू नहीं बदली जा सकती.

  1. एक ऐसा इन्वेंट्री मैप बनाएं जिसमें बदलाव किया जा सके. इसमें, किसी उपकरण की स्ट्रिंग को आइटम की संख्या से मैप किया गया हो. इसमें मछली पकड़ने का जाल जोड़कर इसे बनाएं. इसके बाद, इन्वेंट्री में टैंक साफ़ करने वाले तीन स्क्रबर put() जोड़ें और मछली पकड़ने के जाल को remove() से हटाएं.
val inventory = mutableMapOf("fish net" to 1)
inventory.put("tank scrubber", 3)
println(inventory.toString())
inventory.remove("fish net")
println(inventory.toString())
⇒ {fish net=1, tank scrubber=3}{tank scrubber=3}

इस टास्क में, आपको Kotlin में कॉन्स्टेंट और उन्हें व्यवस्थित करने के अलग-अलग तरीकों के बारे में जानकारी मिलेगी.

पहला चरण: const और val के बारे में जानें

  1. REPL में, कोई संख्यात्मक कॉन्स्टेंट बनाने की कोशिश करें. Kotlin में, टॉप-लेवल के कॉन्स्टेंट बनाए जा सकते हैं. साथ ही, const val का इस्तेमाल करके, उन्हें कंपाइल टाइम पर वैल्यू असाइन की जा सकती है.
const val rocks = 3

वैल्यू असाइन की जाती है और उसे बदला नहीं जा सकता. यह सामान्य val को तय करने जैसा है. तो const val और val में क्या अंतर है? const val की वैल्यू को कंपाइल टाइम पर तय किया जाता है. वहीं, val की वैल्यू को प्रोग्राम के एक्ज़ीक्यूशन के दौरान तय किया जाता है. इसका मतलब है कि val को रन टाइम पर किसी फ़ंक्शन से असाइन किया जा सकता है.

इसका मतलब है कि val को किसी फ़ंक्शन से वैल्यू असाइन की जा सकती है, लेकिन const val को नहीं.

val value1 = complexFunctionCall() // OK
const val CONSTANT1 = complexFunctionCall() // NOT ok

इसके अलावा, const val सिर्फ़ टॉप लेवल पर काम करता है. साथ ही, यह object के साथ डिक्लेयर की गई सिंगलटन क्लास में काम करता है, न कि रेगुलर क्लास में. इसका इस्तेमाल, सिर्फ़ कॉन्स्टेंट वाली फ़ाइल या सिंगलटन ऑब्जेक्ट बनाने के लिए किया जा सकता है. साथ ही, इन्हें ज़रूरत के हिसाब से इंपोर्ट किया जा सकता है.

object Constants {
    const val CONSTANT2 = "object constant"
}
val foo = Constants.CONSTANT2

दूसरा चरण: कंपैनियन ऑब्जेक्ट बनाना

Kotlin में क्लास लेवल के कॉन्स्टेंट का कोई कॉन्सेप्ट नहीं है.

किसी क्लास में कॉन्स्टेंट तय करने के लिए, आपको उन्हें companion कीवर्ड के साथ घोषित किए गए कंपैनियन ऑब्जेक्ट में रैप करना होगा. कंपैनियन ऑब्जेक्ट, क्लास में मौजूद एक सिंगलटन ऑब्जेक्ट होता है.

  1. स्ट्रिंग कॉन्स्टेंट वाला कंपैनियन ऑब्जेक्ट इस्तेमाल करके कोई क्लास बनाएं.
class MyClass {
    companion object {
        const val CONSTANT3 = "constant in companion"
    }
}

कंपैनियन ऑब्जेक्ट और सामान्य ऑब्जेक्ट के बीच बुनियादी अंतर यह है कि:

  • कंपैनियन ऑब्जेक्ट, कंटेनिंग क्लास के स्टैटिक कंस्ट्रक्टर से शुरू किए जाते हैं. इसका मतलब है कि जब ऑब्जेक्ट बनाया जाता है, तब उन्हें बनाया जाता है.
  • रेगुलर ऑब्जेक्ट को पहली बार ऐक्सेस करने पर, उन्हें लेज़ी तरीके से शुरू किया जाता है. इसका मतलब है कि जब उनका पहली बार इस्तेमाल किया जाता है.

इसके अलावा, और भी कई चीज़ें हैं. हालांकि, फ़िलहाल आपको सिर्फ़ इतना जानना है कि क्लास में मौजूद कॉन्स्टेंट को कंपैनियन ऑब्जेक्ट में रैप किया जाता है.

इस टास्क में, आपको क्लास के व्यवहार को बढ़ाने के बारे में जानकारी मिलती है. किसी क्लास के व्यवहार को बढ़ाने के लिए, यूटिलिटी फ़ंक्शन लिखना बहुत आम बात है. Kotlin, इन यूटिलिटी फ़ंक्शन को एलान करने के लिए एक आसान सिंटैक्स उपलब्ध कराता है: एक्सटेंशन फ़ंक्शन.

एक्सटेंशन फ़ंक्शन की मदद से, किसी मौजूदा क्लास में फ़ंक्शन जोड़े जा सकते हैं. इसके लिए, आपको उसके सोर्स कोड को ऐक्सेस करने की ज़रूरत नहीं होती. उदाहरण के लिए, उन्हें Extensions.kt फ़ाइल में एलान किया जा सकता है. यह फ़ाइल आपके पैकेज का हिस्सा होती है. इससे क्लास में कोई बदलाव नहीं होता. हालांकि, इससे आपको उस क्लास के ऑब्जेक्ट पर फ़ंक्शन कॉल करते समय, डॉट-नोटेशन का इस्तेमाल करने की अनुमति मिलती है.

पहला चरण: एक्सटेंशन फ़ंक्शन लिखना

  1. REPL में काम करते समय, एक सामान्य एक्सटेंशन फ़ंक्शन hasSpaces() लिखें. इससे यह पता चलेगा कि किसी स्ट्रिंग में स्पेस हैं या नहीं. फ़ंक्शन के नाम से पहले, उस क्लास का नाम लिखा जाता है जिस पर वह काम करता है. फ़ंक्शन के अंदर, this उस ऑब्जेक्ट को दिखाता है जिस पर इसे कॉल किया जाता है. वहीं, it, find() कॉल में मौजूद इटरेटर को दिखाता है.
fun String.hasSpaces(): Boolean {
    val found = this.find { it == ' ' }
    return found != null
}
println("Does it have spaces?".hasSpaces())
⇒ true
  1. hasSpaces() फ़ंक्शन को आसान बनाया जा सकता है. this की साफ़ तौर पर ज़रूरत नहीं है. साथ ही, फ़ंक्शन को एक एक्सप्रेशन में बदला जा सकता है और उसे रिटर्न किया जा सकता है. इसलिए, इसके चारों ओर कर्ली ब्रैकेट {} की भी ज़रूरत नहीं है.
fun String.hasSpaces() = find { it == ' ' } != null

दूसरा चरण: एक्सटेंशन इस्तेमाल करने से जुड़ी सीमाओं के बारे में जानें

एक्सटेंशन फ़ंक्शन के पास, सिर्फ़ उस क्लास के सार्वजनिक एपीआई का ऐक्सेस होता है जिसे वे एक्सटेंड कर रहे हैं. private वाले वैरिएबल को ऐक्सेस नहीं किया जा सकता.

  1. private के तौर पर मार्क की गई प्रॉपर्टी में एक्सटेंशन फ़ंक्शन जोड़ने की कोशिश करें.
class AquariumPlant(val color: String, private val size: Int)

fun AquariumPlant.isRed() = color == "red"    // OK
fun AquariumPlant.isBig() = size > 50         // gives error
⇒ error: cannot access 'size': it is private in 'AquariumPlant'
  1. नीचे दिए गए कोड की जांच करें और पता लगाएं कि यह क्या प्रिंट करेगा.
open class AquariumPlant(val color: String, private val size: Int)

class GreenLeafyPlant(size: Int) : AquariumPlant("green", size)

fun AquariumPlant.print() = println("AquariumPlant")
fun GreenLeafyPlant.print() = println("GreenLeafyPlant")

val plant = GreenLeafyPlant(size = 10)
plant.print()
println("\n")
val aquariumPlant: AquariumPlant = plant
aquariumPlant.print()  // what will it print?
⇒ GreenLeafyPlant
AquariumPlant

plant.print() प्रिंट GreenLeafyPlant. आपको लग सकता है कि aquariumPlant.print() भी GreenLeafyPlant प्रिंट करेगा, क्योंकि इसे plant की वैल्यू असाइन की गई थी. हालांकि, टाइप को कंपाइल करने के दौरान रिज़ॉल्व किया जाता है. इसलिए, AquariumPlant प्रिंट होता है.

तीसरा चरण: एक्सटेंशन प्रॉपर्टी जोड़ना

एक्सटेंशन फ़ंक्शन के अलावा, Kotlin में एक्सटेंशन प्रॉपर्टी भी जोड़ी जा सकती हैं. एक्सटेंशन फ़ंक्शन की तरह, आपको उस क्लास के बारे में बताना होता है जिसे एक्सटेंड किया जा रहा है. इसके बाद, एक बिंदु और फिर प्रॉपर्टी का नाम लिखना होता है.

  1. REPL में काम करते समय, AquariumPlant में एक्सटेंशन प्रॉपर्टी isGreen जोड़ें. अगर रंग हरा है, तो isGreen की वैल्यू true होगी.
val AquariumPlant.isGreen: Boolean
   get() = color == "green"

isGreen प्रॉपर्टी को सामान्य प्रॉपर्टी की तरह ही ऐक्सेस किया जा सकता है. ऐक्सेस करने पर, वैल्यू पाने के लिए isGreen के लिए गेटर को कॉल किया जाता है.

  1. aquariumPlant वैरिएबल के लिए isGreen प्रॉपर्टी प्रिंट करें और नतीजे देखें.
aquariumPlant.isGreen
⇒ res4: kotlin.Boolean = true

चौथा चरण: नल वैल्यू स्वीकार करने वाले रिसीवर के बारे में जानना

जिस क्लास को बढ़ाया जाता है उसे रिसीवर कहा जाता है. इस क्लास को नल बनाया जा सकता है. ऐसा करने पर, बॉडी में इस्तेमाल किया गया this वैरिएबल null हो सकता है. इसलिए, इसकी जांच ज़रूर करें. अगर आपको लगता है कि कॉलर, शून्य हो सकने वाले वैरिएबल पर आपकी एक्सटेंशन विधि को कॉल करना चाहेंगे या अगर आपको null पर लागू होने पर अपने फ़ंक्शन का डिफ़ॉल्ट व्यवहार देना है, तो आपको शून्य हो सकने वाला रिसीवर लेना होगा.

  1. REPL में काम जारी रखें. एक pull() तरीका तय करें, जो नल हो सकने वाला रिसीवर लेता है. इसे टाइप के बाद, बिंदु से पहले सवाल के निशान ? से दिखाया जाता है. बॉडी के अंदर, यह जांच की जा सकती है कि this, null नहीं है. इसके लिए, questionmark-dot-apply ?.apply. का इस्तेमाल करें
fun AquariumPlant?.pull() {
   this?.apply {
       println("removing $this")
   }
}

val plant: AquariumPlant? = null
plant.pull()
  1. इस मामले में, प्रोग्राम चलाने पर कोई आउटपुट नहीं मिलता. plant की वैल्यू null होने की वजह से, इनर println() को कॉल नहीं किया जाता.

एक्सटेंशन फ़ंक्शन बहुत असरदार होते हैं. Kotlin की ज़्यादातर स्टैंडर्ड लाइब्रेरी, एक्सटेंशन फ़ंक्शन के तौर पर लागू की जाती है.

इस सबक में, आपने कलेक्शन के बारे में ज़्यादा जाना. साथ ही, आपने कॉन्स्टेंट के बारे में जाना. इसके अलावा, आपने एक्सटेंशन फ़ंक्शन और प्रॉपर्टी की ताकत के बारे में भी जाना.

  • जोड़ों और तीन वैल्यू वाले टपल का इस्तेमाल करके, किसी फ़ंक्शन से एक से ज़्यादा वैल्यू दिखाई जा सकती हैं. उदाहरण के लिए:
    val twoLists = fish.partition { isFreshWater(it) }
  • Kotlin में List के लिए कई काम के फ़ंक्शन होते हैं. जैसे, reversed(), contains(), और subList().
  • कुंजियों को वैल्यू से मैप करने के लिए, HashMap का इस्तेमाल किया जा सकता है. उदाहरण के लिए:
    val cures = hashMapOf("white spots" to "Ich", "red sores" to "hole disease")
  • const कीवर्ड का इस्तेमाल करके, कंपाइल-टाइम कॉन्स्टेंट का एलान करें. इन्हें टॉप लेवल पर रखा जा सकता है, सिंगलटन ऑब्जेक्ट में व्यवस्थित किया जा सकता है या कंपैनियन ऑब्जेक्ट में रखा जा सकता है.
  • कंपैनियन ऑब्जेक्ट, क्लास की परिभाषा में मौजूद एक सिंगलटन ऑब्जेक्ट होता है. इसे companion कीवर्ड के साथ तय किया जाता है.
  • एक्सटेंशन फ़ंक्शन और प्रॉपर्टी, किसी क्लास में फ़ंक्शनैलिटी जोड़ सकती हैं. उदाहरण के लिए:
    fun String.hasSpaces() = find { it == ' ' } != null
  • नल हो सकने वाले रिसीवर की मदद से, किसी क्लास पर एक्सटेंशन बनाए जा सकते हैं. ये एक्सटेंशन null हो सकते हैं. कोड को लागू करने से पहले, null की जांच करने के लिए, ?. ऑपरेटर को apply के साथ जोड़ा जा सकता है. उदाहरण के लिए:
    this?.apply { println("removing $this") }

Kotlin का दस्तावेज़

अगर आपको इस कोर्स के किसी विषय के बारे में ज़्यादा जानकारी चाहिए या आपको कोई समस्या आ रही है, तो https://kotlinlang.org पर जाएं.

Kotlin के ट्यूटोरियल

https://try.kotlinlang.org वेबसाइट पर, Kotlin Koans नाम के रिच ट्यूटोरियल, वेब पर आधारित इंटरप्रेटर, और उदाहरणों के साथ रेफ़रंस दस्तावेज़ों का पूरा सेट शामिल है.

Udacity कोर्स

इस विषय पर Udacity का कोर्स देखने के लिए, Kotlin Bootcamp for Programmers पर जाएं.

IntelliJ IDEA

IntelliJ IDEA के लिए दस्तावेज़, JetBrains की वेबसाइट पर उपलब्ध हैं.

इस सेक्शन में, उन छात्र-छात्राओं के लिए होमवर्क असाइनमेंट की सूची दी गई है जो किसी शिक्षक के कोर्स के हिस्से के तौर पर इस कोडलैब पर काम कर रहे हैं. शिक्षक के पास ये विकल्प होते हैं:

  • अगर ज़रूरी हो, तो होमवर्क असाइन करें.
  • छात्र-छात्राओं को बताएं कि होमवर्क असाइनमेंट कैसे सबमिट किए जाते हैं.
  • होमवर्क असाइनमेंट को ग्रेड दें.

शिक्षक इन सुझावों का इस्तेमाल अपनी ज़रूरत के हिसाब से कर सकते हैं. साथ ही, वे चाहें, तो कोई दूसरा होमवर्क भी दे सकते हैं.

अगर आपको यह कोडलैब खुद से पूरा करना है, तो अपनी जानकारी की जांच करने के लिए, इन होमवर्क असाइनमेंट का इस्तेमाल करें.

इन सवालों के जवाब दें

पहला सवाल

इनमें से कौनसी फ़ंक्शन, सूची की कॉपी दिखाता है?

add()

remove()

reversed()

contains()

दूसरा सवाल

class AquariumPlant(val color: String, val size: Int, private val cost: Double, val leafy: Boolean) पर इनमें से कौनसे एक्सटेंशन फ़ंक्शन से कंपाइलर को गड़बड़ी मिलेगी?

fun AquariumPlant.isRed() = color == "red"

fun AquariumPlant.isBig() = size > 45

fun AquariumPlant.isExpensive() = cost > 10.00

fun AquariumPlant.isNotLeafy() = leafy == false

तीसरा सवाल

इनमें से कौनसी ऐसी जगह नहीं है जहां const val का इस्तेमाल करके कॉन्स्टेंट तय किए जा सकते हैं?

▢ फ़ाइल के टॉप लेवल पर

▢ रेगुलर क्लास में

▢ सिंगलटन ऑब्जेक्ट में

▢ कंपैनियन ऑब्जेक्ट में

अगले लेसन पर जाएं: 5.2 Generics

कोर्स की खास जानकारी और अन्य कोडलैब के लिंक देखने के लिए, "प्रोग्रामर के लिए Kotlin बूटकैंप: कोर्स में आपका स्वागत है." लेख पढ़ें