Kotlin प्रोग्रामिंग लैंग्वेज सीखें

Kotlin एक प्रोग्रामिंग भाषा है इसे Android डेवलपर हर जगह इस्तेमाल करते हैं. यह विषय Kotlin की तरह काम करता है क्रैश-कोर्स का इस्तेमाल करें.

वैरिएबल की जानकारी

Kotlin, वैरिएबल के बारे में बताने के लिए दो अलग-अलग कीवर्ड का इस्तेमाल करती है: val और var.

  • उस वैरिएबल के लिए val का इस्तेमाल करें जिसकी वैल्यू कभी नहीं बदलती. आप कोई मान फिर से असाइन नहीं कर सकते को val का इस्तेमाल करके बताया गया था.
  • उस वैरिएबल के लिए var का इस्तेमाल करें जिसकी वैल्यू बदल सकती है.

नीचे दिए गए उदाहरण में, count Int टाइप का एक वैरिएबल है. इसे 10 की शुरुआती वैल्यू:

var count: Int = 10

Int एक ऐसा टाइप है जो पूर्णांक को दिखाता है. यह संख्या वाले उन टाइप में से एक है जो को Kotlin में दिखाया जा सकता है. अन्य भाषाओं के समान, आप इसका उपयोग आपके संख्या वाले डेटा के आधार पर Byte, Short, Long, Float, और Double.

var कीवर्ड का मतलब है कि आपके पास ज़रूरत के हिसाब से count को वैल्यू फिर से असाइन करने का विकल्प है. इसके लिए उदाहरण के लिए, आपके पास count की वैल्यू को 10 से बदलकर 15 करने का विकल्प है:

var count: Int = 10
count = 15

हालांकि, कुछ वैल्यू बदलने के लिए नहीं होती हैं. इसे String languageName. अगर आपको यह पक्का करना है कि languageName में एक वैल्यू हमेशा बनी रहे "Kotlin" का इस्तेमाल किया है, तो val कीवर्ड का इस्तेमाल करके languageName का एलान किया जा सकता है:

val languageName: String = "Kotlin"

इन कीवर्ड की मदद से, यह साफ़ तौर पर बताया जा सकता है कि क्या बदलाव किए जा सकते हैं. इन कामों के लिए इनका इस्तेमाल करें का लाभ उठाएं. अगर वैरिएबल रेफ़रंस को फिर से असाइन करना ज़रूरी है, तो एलान करें कि यह var है. अगर ऐसा नहीं है, तो val का इस्तेमाल करें.

टाइप का अनुमान

ऊपर दिए गए उदाहरण में, जब आपने languageName है, तो Kotlin कंपाइलर, टाइप का अनुमान लगाने के लिए, असाइन की गई वैल्यू.

"Kotlin" की वैल्यू String टाइप की है, इसलिए कंपाइलर यह अनुमान लगाता है कि languageName एक String भी है. ध्यान दें कि Kotlin एक स्टैटिक टाइप किया गया है भाषा. इसका मतलब है कि इस टाइप को कंपाइल करते समय रिज़ॉल्व किया जाता है और कभी भी ऐसा नहीं किया जाता बदलाव.

नीचे दिए गए उदाहरण में, languageName का अनुमान String के तौर पर लगाया गया है. इसलिए, ये काम नहीं किए जा सकते ऐसे किसी भी फ़ंक्शन को कॉल करें जो String क्लास का हिस्सा नहीं हैं:

val languageName = "Kotlin"
val upperCaseName = languageName.toUpperCase()

// Fails to compile
languageName.inc()

toUpperCase() एक ऐसा फ़ंक्शन है जिसे सिर्फ़ टाइप के वैरिएबल पर ही कॉल किया जा सकता है String. Kotlin कंपाइलर ने languageName का अनुमान String के तौर पर लगाया है, आप toUpperCase() पर सुरक्षित तरीके से कॉल कर सकते हैं. हालांकि, inc() एक Int ऑपरेटर है फ़ंक्शन है, इसलिए इसे String पर कॉल नहीं किया जा सकता. टाइप करने के लिए Kotlin की प्रोसेस अनुमान से आपको कम से कम शब्द और टाइप-सेफ़्टी, दोनों मिलती है.

कोई सेफ़्टी (सुरक्षा) नहीं

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

// Fails to compile
val languageName: String = null

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

val languageName: String? = null

String? टाइप का इस्तेमाल करके, इन लक्ष्यों के लिए String वैल्यू या null असाइन की जा सकती है languageName.

आपको शून्य हो सकने वाले वैरिएबल को ध्यान से मैनेज करना चाहिए या फिर जोखिम वाले वैरिएबल का जोखिम लेना चाहिए NullPointerException. उदाहरण के लिए, Java में अगर आपने किसी तरीके को शून्य वैल्यू होने पर, आपका प्रोग्राम क्रैश हो जाता है.

Kotlin, शून्य किए जा सकने वाले टूल के साथ सुरक्षित तरीके से काम करने के लिए, कई तरीके उपलब्ध कराती है वैरिएबल. ज़्यादा जानकारी के लिए, यह देखें Android में सामान्य Kotlin पैटर्न: शून्य होने की क्षमता.

कंडीशनल

Kotlin में कंडिशनल लॉजिक को लागू करने के लिए, कई मैकेनिज़्म होते हैं. सबसे ज़्यादा इनमें से एक आम if-else स्टेटमेंट है. अगर कोई एक्सप्रेशन रैप किया हुआ हो if के बगल में मौजूद ब्रैकेट की वैल्यू true आती है. इसके बाद, कोड के अंदर कोड होता है वह ब्रांच (उदाहरण के लिए, जो तुरंत बाद में आने वाला कोड है, जिसे कर्ली लाइन में रैप किया गया है) (ब्रेसेस) चलाए जाते हैं. ऐसा नहीं करने पर, else ब्रांच में मौजूद कोड को एक्ज़ीक्यूट किया जाता है.

if (count == 42) {
    println("I have the answer.")
} else {
    println("The answer eludes me.")
}

else if का इस्तेमाल करके, कई शर्तें दिखाई जा सकती हैं. इसकी मदद से, आपको एक कंडिशनल स्टेटमेंट में ज़्यादा जानकारी वाला और मुश्किल लॉजिक, जैसा कि यहां दिखाया गया है नीचे दिया गया उदाहरण:

if (count == 42) {
    println("I have the answer.")
} else if (count > 35) {
    println("The answer is close.")
} else {
    println("The answer eludes me.")
}

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

val answerString: String = if (count == 42) {
    "I have the answer."
} else if (count > 35) {
    "The answer is close."
} else {
    "The answer eludes me."
}

println(answerString)

इसका मतलब है कि हर कंडीशनल ब्रांच अपने फ़ाइनल लाइन में दी गई जानकारी के मुताबिक, आपको return कीवर्ड का इस्तेमाल करने की ज़रूरत नहीं होगी. क्योंकि सभी तीनों ब्रांच String टाइप की हैं, if-else एक्सप्रेशन का नतीजा यह होता है String टाइप का भी. इस उदाहरण में, answerString को एक नाम दिया गया है if-else एक्सप्रेशन के नतीजे से मिलने वाली वैल्यू. टाइप के अनुमान का इस्तेमाल, answerString के लिए साफ़ तौर पर जानकारी देने वाले टाइप की जानकारी को छोड़ दें, लेकिन यह अक्सर अच्छा रहता है तो उसे आसान बना सकें.

आपके कंडिशनल स्टेटमेंट की जटिलता बढ़ने पर, आपको अपने if-else एक्सप्रेशन को WHEN एक्सप्रेशन से बदलना, जैसा कि नीचे दिया गया उदाहरण:

val answerString = when {
    count == 42 -> "I have the answer."
    count > 35 -> "The answer is close."
    else -> "The answer eludes me."
}

println(answerString)

when एक्सप्रेशन में मौजूद हर ब्रांच को एक ऐरो से दिखाया जाता है. (->), और नतीजा. अगर तीर के बाईं ओर स्थिति सही का आकलन करता है, तो दाईं ओर के एक्सप्रेशन का नतीजा यह होता है वापस किया गया. ध्यान दें कि एक्ज़ीक्यूशन एक ब्रांच से दूसरी ब्रांच में नहीं जाता. when एक्सप्रेशन के उदाहरण में दिया गया कोड, जोड़ा गया है, लेकिन यह पढ़ने में आसान है.

Kotlin की कंडिशनल इसकी सबसे ज़्यादा असरदार सुविधाओं में से एक को हाइलाइट करती हैं, स्मार्ट कास्ट करने की सुविधा का इस्तेमाल करें. सुरक्षित-कॉल ऑपरेटर या NOT-शून्य का इस्तेमाल करने के बजाय दावा ऑपरेटर का इस्तेमाल शून्य वैल्यू के साथ काम करने के लिए किया जाता है. इसके बजाय, यह जांच की जा सकती है कि वैरिएबल में खाली जगह की वैल्यू का रेफ़रंस है. इसमें कंडिशनल स्टेटमेंट का इस्तेमाल किया गया है, जैसे कि नीचे दिए गए उदाहरण में दिखाया गया है:

val languageName: String? = null
if (languageName != null) {
    // No need to write languageName?.toUpperCase()
    println(languageName.toUpperCase())
}

कंडीशनल ब्रांच में, languageName को शून्य नहीं माना जा सकता. Kotlin की मदद से यह पता लगाया जा सकता है कि ब्रांच को एक्ज़ीक्यूट करने की कंडीशन यह है कि languageName में कोई शून्य वैल्यू नहीं होती है. इसलिए, आपको उस ब्रांच में languageName को शून्य के तौर पर डाला गया हो. स्मार्ट कास्ट करने की यह सुविधा, शून्य के लिए काम करती है चेक, टाइप की जांच, या आपसे जुड़ी शर्तों को पूरा करने वाली कोई भी शर्त कॉन्ट्रैक्ट.

फ़ंक्शन

किसी फ़ंक्शन में एक या उससे ज़्यादा एक्सप्रेशन को ग्रुप किया जा सकता है. दोहराने के बजाय हर बार किसी नतीजे की ज़रूरत होने पर एक्सप्रेशन की एक ही सीरीज़ होती है, तो आप किसी फ़ंक्शन में एक्सप्रेशन को शामिल करता है और उसके बजाय उस फ़ंक्शन को कॉल करता है.

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

पिछले उदाहरणों के आधार पर, यहां Kotlin के पूरे फ़ंक्शन के बारे में बताया गया है:

fun generateAnswerString(): String {
    val answerString = if (count == 42) {
        "I have the answer."
    } else {
        "The answer eludes me"
    }

    return answerString
}

ऊपर दिए गए उदाहरण में मौजूद फ़ंक्शन का नाम generateAnswerString है. यह कोई इनपुट नहीं लेता. यह String टाइप का नतीजा देता है. किसी फ़ंक्शन को शामिल करना है, तो इसके नाम के बाद इनवोकेशन ऑपरेटर (()) का इस्तेमाल करें. इस नीचे दिए गए उदाहरण के मुताबिक, answerString वैरिएबल को शुरू किए गए वैल्यू से मिले नतीजे से शुरू किया गया है generateAnswerString().

val answerString = generateAnswerString()

फ़ंक्शन, इनपुट के तौर पर आर्ग्युमेंट ले सकते हैं, जैसा कि इस उदाहरण में दिखाया गया है:

fun generateAnswerString(countThreshold: Int): String {
    val answerString = if (count > countThreshold) {
        "I have the answer."
    } else {
        "The answer eludes me."
    }

    return answerString
}

फ़ंक्शन का एलान करते समय, जितने चाहें उतने आर्ग्युमेंट और उनके प्रकार. ऊपर दिए गए उदाहरण में, generateAnswerString() Int टाइप का countThreshold. फ़ंक्शन में, आपके पास दर्ज करें.

इस फ़ंक्शन को कॉल करते समय, आपको फ़ंक्शन में एक तर्क शामिल करना होगा कॉल के लिए ब्रैकेट:

val answerString = generateAnswerString(42)

फ़ंक्शन की जानकारी को आसान बनाना

generateAnswerString() फ़ंक्शन बहुत आसान है. फ़ंक्शन बताता है कि वैरिएबल सेट करके फिर तुरंत वापस आ जाता है. जब सिंगल एक्सप्रेशन का नतीजा यह होता है फ़ंक्शन से लौटाया जाता है, तो आप सीधे तौर पर स्थानीय वैरिएबल का एलान करना छोड़ सकते हैं फ़ंक्शन में मौजूद if-else एक्सप्रेशन का नतीजा लौटाकर, जैसे कि नीचे दिए गए उदाहरण में दिखाया गया है:

fun generateAnswerString(countThreshold: Int): String {
    return if (count > countThreshold) {
        "I have the answer."
    } else {
        "The answer eludes me."
    }
}

आपके पास रिटर्न कीवर्ड को असाइनमेंट ऑपरेटर से बदलने का विकल्प भी है:

fun generateAnswerString(countThreshold: Int): String = if (count > countThreshold) {
        "I have the answer"
    } else {
        "The answer eludes me"
    }

अनाम फ़ंक्शन

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

val stringLengthFunc: (String) -> Int = { input ->
    input.length
}

नाम वाले फ़ंक्शन की तरह, पहचान छिपाने वाले फ़ंक्शन में किसी भी संख्या में एक्सप्रेशन हो सकते हैं. फ़ंक्शन की रिटर्न वैल्यू, फ़ाइनल एक्सप्रेशन का नतीजा होती है.

ऊपर दिए गए उदाहरण में, stringLengthFunc में एक पहचान छिपाने वाला रेफ़रंस शामिल है फ़ंक्शन जो इनपुट के रूप में String को लेता है और इनपुट की लंबाई देता है Int टाइप के आउटपुट के तौर पर String. इस वजह से, फ़ंक्शन का टाइप (String) -> Int के तौर पर दिखाया गया है. हालांकि, यह कोड फ़ंक्शन शुरू नहीं करता है. फ़ंक्शन का नतीजा वापस पाने के लिए, आपको इसे उसी तरह शुरू करना होगा जैसे आप नाम वाला फ़ंक्शन. stringLengthFunc पर कॉल करते समय आपको String देना होगा, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:

val stringLengthFunc: (String) -> Int = { input ->
    input.length
}

val stringLength: Int = stringLengthFunc("Android")

हाई-ऑर्डर फ़ंक्शन

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

यहां हाई-ऑर्डर फ़ंक्शन का एक उदाहरण दिया गया है:

fun stringMapper(str: String, mapper: (String) -> Int): Int {
    // Invoke function
    return mapper(str)
}

stringMapper() फ़ंक्शन, String के साथ एक फ़ंक्शन लेता है, जो इसमें, पास की गई String से Int वैल्यू हासिल होती है.

आप String और एक फ़ंक्शन को पास करके, stringMapper() को कॉल कर सकते हैं दूसरे इनपुट पैरामीटर को पूरा करता है, यानी वह फ़ंक्शन जो String को Int इनपुट और आउटपुट देता है, जैसा कि इस उदाहरण में दिखाया गया है:

stringMapper("Android", { input ->
    input.length
})

अगर किसी फ़ंक्शन पर तय किया गया लास्ट पैरामीटर, पहचान छिपाने वाला फ़ंक्शन है, तो ये काम किए जा सकते हैं इसे फ़ंक्शन शुरू करने के लिए इस्तेमाल किए गए ब्रैकेट के बाहर पास करें, जैसा कि नीचे दिया गया उदाहरण:

stringMapper("Android") { input ->
    input.length
}

बिना नाम वाले फ़ंक्शन, Kotlin की स्टैंडर्ड लाइब्रेरी में देखे जा सकते हैं. इसके लिए ज़्यादा जानकारी के लिए, देखें हाई-ऑर्डर फ़ंक्शन और Lambdas.

कक्षाएं

अब तक बताए गए सभी टाइप, Kotlin प्रोग्रामिंग में बनाए गए हैं भाषा. अगर आपको अपना कस्टम टाइप जोड़ना है, तो क्लास तय करें class कीवर्ड का इस्तेमाल करके, जैसा कि इस उदाहरण में दिखाया गया है:

class Car

प्रॉपर्टी

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

class Car {
    val wheels = listOf<Wheel>()
}

ध्यान दें कि wheels एक public val है. इसका मतलब है कि wheels को यहां से ऐक्सेस किया जा सकता है Car क्लास के बाहर है और उसे फिर से असाइन नहीं किया जा सकता. अगर आपको इंस्टेंस Car का है, तो आपको पहले इसके कंस्ट्रक्टर को कॉल करना होगा. यहां से, ये काम किए जा सकते हैं साथ ही, इसकी सभी ऐक्सेस की जा सकने वाली प्रॉपर्टी को ऐक्सेस कर सकते हैं.

val car = Car() // construct a Car
val wheels = car.wheels // retrieve the wheels value from the Car

अगर आपको व्हील को अपनी पसंद के मुताबिक बनाना है, तो ऐसा कस्टम कंस्ट्रक्टर बनाएं जो बताता है कि आपकी क्लास की प्रॉपर्टी कैसे शुरू की जाती हैं:

class Car(val wheels: List<Wheel>)

ऊपर दिए गए उदाहरण में, क्लास कंस्ट्रक्टर, List<Wheel> को कंस्ट्रक्टर आर्ग्युमेंट और उस तर्क का इस्तेमाल अपने wheels को शुरू करने के लिए करता है प्रॉपर्टी.

क्लास फ़ंक्शन और एनकैप्सुलेशन

क्लास, फ़ंक्शन का इस्तेमाल व्यवहार का मॉडल बनाने के लिए करती हैं. फ़ंक्शन, स्थिति में बदलाव कर सकते हैं. इससे आपको को सिर्फ़ वह डेटा दिखाएं जिसे आपको सार्वजनिक करना है. यह ऐक्सेस कंट्रोल इसका हिस्सा है: एक बड़ा ऑब्जेक्ट-ओरिएंटेड कॉन्सेप्ट है जिसे एनकैप्सुलेशन के नाम से जाना जाता है.

यहां दिए गए उदाहरण में, doorLock प्रॉपर्टी को किसी भी चीज़ से निजी रखा जाता है Car क्लास के बाहर है. कार अनलॉक करने के लिए, आपको unlockDoor() पर कॉल करना होगा फ़ंक्शन को किसी मान्य कुंजी के साथ पास किया जा रहा है, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:

class Car(val wheels: List<Wheel>) {

    private val doorLock: DoorLock = ...

    fun unlockDoor(key: Key): Boolean {
        // Return true if key is valid for door lock, false otherwise
    }
}

अगर आपको अपनी ज़रूरत के हिसाब से यह तय करना है कि किसी प्रॉपर्टी का रेफ़रंस कैसे दिया जाए, तो कस्टम गैटर और सेटर. उदाहरण के लिए, अगर आपको किसी प्रॉपर्टी की गैटर अपने सेटर पर पहुंच प्रतिबंधित करते हुए, आप उस सेटर को private:

class Car(val wheels: List<Wheel>) {

    private val doorLock: DoorLock = ...

    var gallonsOfFuelInTank: Int = 15
        private set

    fun unlockDoor(key: Key): Boolean {
        // Return true if key is valid for door lock, false otherwise
    }
}

प्रॉपर्टी और फ़ंक्शन को मिलाकर, ऐसी क्लास बनाई जा सकती हैं जो हर तरह के ऑब्जेक्ट को मॉडल कर सकते हैं.

इंटरऑपरेबिलिटी (दूसरे सिस्टम के साथ काम करना)

Kotlin की सबसे अहम सुविधाओं में से एक है Java के साथ इसका फ़्लूइड इंटरऑपरेबिलिटी. Kotlin कोड, JVM बाइटकोड को कंपाइल करता है, इसलिए आपका Kotlin कोड कॉल कर सकता है आप उन्हें सीधे Java कोड में और इसके उलटा क्रम में इस्तेमाल कर सकते हैं. इसका मतलब है कि आपको विज्ञापन की परफ़ॉर्मेंस को मौजूदा Java लाइब्रेरी को सीधे Kotlin से. इसके अलावा, ज़्यादातर लोग Android के एपीआई, Java में लिखे गए हैं और उन्हें सीधे Kotlin से कॉल किया जा सकता है.

अगले चरण

Kotlin एक आसान और व्यावहारिक भाषा है, जो बढ़ती हुई सहायता और गति के साथ काम करती है. बुध अगर आपने अभी तक इसे नहीं आज़माया है, तो कृपया इसे आज़माने के लिए प्रोत्साहित करें. आगे के चरणों के बारे में जानने के लिए, इस पर एक नज़र डालें Kotlin के आधिकारिक दस्तावेज़ पर जाएं साथ ही, YPP में शामिल होने के लिए आवेदन करने का तरीका आपके Android ऐप्लिकेशन में सामान्य Kotlin पैटर्न.