यह दस्तावेज़, Kotlin प्रोग्रामिंग लैंग्वेज में सोर्स कोड के लिए Google के Android कोडिंग स्टैंडर्ड की पूरी जानकारी देता है. Kotlin की सोर्स फ़ाइल को Google Android स्टाइल में बताया जाता है, बशर्ते वह यहां दिए गए नियमों का पालन करती हो.
अन्य प्रोग्रामिंग स्टाइल गाइड की तरह, इन समस्याओं में फ़ॉर्मैटिंग से जुड़ी सुंदर समस्याओं के साथ-साथ, दूसरी तरह के कन्वेंशन या कोडिंग स्टैंडर्ड भी शामिल किए गए. हालांकि, इस दस्तावेज़ में मुख्य तौर पर उन नियमों के बारे में बताया गया है जिनका पालन हम पूरी तरह से करते हैं. साथ ही, इसमें कोई ऐसी सलाह नहीं दी गई है जिस पर साफ़ तौर पर कोई पाबंदी नहीं होती (चाहे कोई व्यक्ति हो या टूल).
स्रोत फ़ाइलें
सभी सोर्स फ़ाइलें UTF-8 के तौर पर कोड में बदली जानी चाहिए.
इन्हें
अगर किसी सोर्स फ़ाइल में सिर्फ़ एक टॉप-लेवल क्लास है, तो फ़ाइल का नाम
केस-सेंसिटिव (बड़े और छोटे अक्षरों में अंतर) नाम के साथ-साथ .kt
एक्सटेंशन भी दिखना चाहिए. या फिर,
अगर किसी सोर्स फ़ाइल में कई टॉप लेवल एलान शामिल हैं, तो कोई नाम चुनें
जो फ़ाइल की सामग्री के बारे में बताता है, तब PascalCase लागू करें (camelCase है
स्वीकार करें, और फ़ाइल नाम बहुवचन है) और .kt
एक्सटेंशन जोड़ें.
// MyClass.kt class MyClass { }
// Bar.kt class Bar { } fun Runnable.toBar(): Bar = // …
// Map.kt fun <T, O> Set<T>.map(func: (T) -> O): List<O> = // … fun <T, O> List<T>.map(func: (T) -> O): List<O> = // …
// extensions.kt fun MyClass.process() = // … fun MyResult.print() = // …
विशेष वर्ण
व्हाइटस्पेस वर्ण
लाइन टर्मिनेटर क्रम के अलावा, ASCII का हॉरिज़ॉन्टल स्पेस वर्ण (0x20) सिर्फ़ खाली सफ़ेद जगह वाला वर्ण है, जो सोर्स फ़ाइल में कहीं भी दिखता है. इसका मतलब है कि:
- स्ट्रिंग और वर्ण की लिटरल वैल्यू में मौजूद बाकी सभी खाली सफ़ेद जगह को छोड़ दिया जाता है.
- टैब के वर्णों का इस्तेमाल इंडेंट करने के लिए नहीं किया जाता.
खास एस्केप सीक्वेंस
खास एस्केप सीक्वेंस वाले किसी भी वर्ण के लिए
(\b
, \n
, \r
, \t
, \'
, \"
, \\
, और \$
),
उस क्रम का इस्तेमाल उससे जुड़े यूनिकोड के बजाय किया जाता है
(उदाहरण के लिए, \u000a
) एस्केप.
बिना ASCII वाले वर्ण
बाकी के गैर-ASCII वर्णों के लिए, असल यूनिकोड वर्ण में
(उदाहरण के लिए, ∞
) या इसके बराबर का यूनिकोड एस्केप (उदाहरण, \u221e
) का इस्तेमाल किया जाता है.
आपकी पसंद इस बात पर निर्भर करती है कि कोड किसने बनाया है
पढ़ने और समझने में आसान होती है.
किसी भी जगह पर प्रिंट किए जा सकने वाले वर्णों के लिए यूनिकोड एस्केप की सलाह दी जाती है
स्ट्रिंग की लिटरल और टिप्पणियों के अलावा, इसे इस्तेमाल करने की सलाह बिलकुल नहीं दी जाती.
उदाहरण | चर्चा |
---|---|
val unitAbbrev = "μs" |
सबसे अच्छा: टिप्पणी के बिना भी पूरी तरह से समझ में आ जाता है. |
val unitAbbrev = "\u03bcs" // μs |
खराब: प्रिंट किए जा सकने वाले वर्ण के साथ एस्केप इस्तेमाल करने की कोई वजह नहीं है. |
val unitAbbrev = "\u03bcs" |
खराब: पाठक को इसके बारे में कोई जानकारी नहीं है. |
return "\ufeff" + content |
अच्छा: प्रिंट न हो सकने वाले वर्णों के लिए Escape का इस्तेमाल करें और ज़रूरी होने पर टिप्पणी करें. |
संरचना
.kt
फ़ाइल में ये चीज़ें शामिल होती हैं:
- कॉपीराइट और/या लाइसेंस का हेडर (ज़रूरी नहीं)
- फ़ाइल के लेवल पर एनोटेशन
- पैकेज स्टेटमेंट
- स्टेटमेंट इंपोर्ट करें
- टॉप लेवल का एलान
सिर्फ़ एक खाली लाइन, इनमें से हर सेक्शन को अलग करती है.
कॉपीराइट / लाइसेंस
अगर फ़ाइल में कॉपीराइट या लाइसेंस हेडर है, तो उसे कई लाइन वाली टिप्पणी में सबसे ऊपर रखना चाहिए.
/* * Copyright 2017 Google, Inc. * * ... */
KDoc शैली का इस्तेमाल न करें टिप्पणी शामिल हो सकती है.
/** * Copyright 2017 Google, Inc. * * ... */
// Copyright 2017 Google, Inc. // // ...
फ़ाइल के लेवल पर एनोटेशन
"फ़ाइल" के साथ एनोटेशन इस्तेमाल के लिए साइट टारगेट इन्हें किसी हेडर टिप्पणी और पैकेज के एलान के बीच में रखा जाता है.
पैकेज स्टेटमेंट
पैकेज स्टेटमेंट पर किसी भी तरह की कॉलम सीमा लागू नहीं होती. साथ ही, इसे कभी भी लाइन-रैप नहीं किया जाता.
स्टेटमेंट इंपोर्ट करें
क्लास, फ़ंक्शन, और प्रॉपर्टी के लिए इंपोर्ट स्टेटमेंट को एक ही सूची में ग्रुप किया जाता है और ASCII क्रम में लगाया जाता है.
वाइल्डकार्ड इंपोर्ट (किसी भी तरह के) की अनुमति नहीं है.
पैकेज स्टेटमेंट की तरह, इंपोर्ट स्टेटमेंट पर कॉलम की सीमा चुन सकते हैं और वे कभी भी लाइन-रैप नहीं होते हैं.
टॉप लेवल का एलान
.kt
फ़ाइल में एक या उससे ज़्यादा टाइप, फ़ंक्शन, प्रॉपर्टी या टाइप का एलान किया जा सकता है
उपनामों को शीर्ष-स्तर पर.
फ़ाइल का कॉन्टेंट एक ही थीम पर फ़ोकस करना चाहिए. इसके उदाहरण एक सार्वजनिक प्रकार या एक्सटेंशन फ़ंक्शन का एक सेट होगा, जो एक से ज़्यादा रिसीवर पर एक ही कार्रवाई होती है. इसमें दी गई जानकारी से जुड़ी जानकारी नहीं होनी चाहिए अलग-अलग फ़ाइलों और सार्वजनिक तौर पर किए जाने वाले एलानों को एक ही फ़ाइल में डालें छोटा किया जाना चाहिए.
कॉन्टेंट के नंबर और क्रम पर, साफ़ तौर पर कोई पाबंदी नहीं लगाई गई है एक फ़ाइल है.
सोर्स फ़ाइलें आम तौर पर ऊपर से नीचे तक पढ़ी जाती हैं, जिसका मतलब है कि इसमें यह दिखाया जाना चाहिए कि ऊपर दी गई जानकारी से आपको सूचना मिलेगी और गहराई से समझना चाहते हैं. अलग-अलग फ़ाइलों को क्रम में लगाया जा सकता है उनकी सामग्री अलग हो. इसी तरह, एक फ़ाइल में 100 प्रॉपर्टी हो सकती हैं, और 10 फ़ंक्शन हैं, और फिर सिंगल क्लास है.
अहम बात यह है कि हर फ़ाइल कुछ लॉजिकल ऑर्डर का इस्तेमाल करती है, जिसे अगर पूछा जाए, तो रखरखाव करने वाला बता सकता है. उदाहरण के लिए, नए फ़ंक्शन सिर्फ़ फ़ाइल के अंत में जोड़ा जाता है, क्योंकि इससे "समय के हिसाब से" जोड़ने की तारीख के हिसाब से" क्रम होता है, जो कोई तर्कपूर्ण क्रम नहीं है.
क्लास के सदस्यों को क्रम में लगाने की सुविधा
क्लास में मौजूद सदस्यों का क्रम, टॉप लेवल के नियमों का ही पालन करता है एलानों को पूरा करना ज़रूरी है.
फ़ॉर्मैटिंग
ब्रेसेस
when
ब्रांच और if
एक्सप्रेशन के लिए, ब्रैकेट की ज़रूरत नहीं होती है
जिसकी एक से ज़्यादा else
ब्रांच नहीं हैं और जो एक लाइन में फ़िट होती हैं.
if (string.isEmpty()) return val result = if (string.isEmpty()) DEFAULT_VALUE else string when (value) { 0 -> return // … }
हालांकि, किसी भी if
, for
, when
ब्रांच, do
, के लिए ब्रैकेट ज़रूरी हैं
और while
स्टेटमेंट और एक्सप्रेशन, भले ही मुख्य भाग खाली हो या उसमें सिर्फ़ शामिल हो
किस वाक्य का इस्तेमाल किया जा सकता है.
if (string.isEmpty()) return // WRONG! if (string.isEmpty()) { return // Okay } if (string.isEmpty()) return // WRONG else doLotsOfProcessingOn(string, otherParametersHere) if (string.isEmpty()) { return // Okay } else { doLotsOfProcessingOn(string, otherParametersHere) }
ऐसे ब्लॉक जो खाली नहीं हैं
इसके लिए, ब्रेसेस कर्नीघन और रिची स्टाइल ("इजिप्शन ब्रैकेट") का पालन करते हैं खाली ब्लॉक और ब्लॉक जैसे कंस्ट्रक्ट:
- ओपनिंग ब्रेस से पहले कोई लाइन ब्रेक नहीं.
- ओपनिंग ब्रेस के बाद लाइन ब्रेक.
- क्लोज़िंग ब्रैकेट से पहले लाइन ब्रेक.
- क्लोज़िंग ब्रैकेट के बाद लाइन ब्रेक, सिर्फ़ तब जब वह ब्रेस किसी
यह स्टेटमेंट बताता है या किसी फ़ंक्शन, कंस्ट्रक्टर या named क्लास के मुख्य हिस्से को खत्म करता है.
उदाहरण के लिए, अगर ब्रेस के बाद इसके बाद लाइन ब्रेक होता है, तो कोई लाइन ब्रेक नहीं होगा
else
या कॉमा.
return Runnable { while (condition()) { foo() } } return object : MyClass() { override fun foo() { if (condition()) { try { something() } catch (e: ProblemException) { recover() } } else if (otherCondition()) { somethingElse() } else { lastThing() } } }
इसके लिए कुछ अपवाद एनम क्लास नीचे दी गई हैं.
खाली ब्लॉक
खाली ब्लॉक या ब्लॉक जैसा निर्माण K&R शैली में होना चाहिए.
try { doSomething() } catch (e: Exception) {} // WRONG!
try { doSomething() } catch (e: Exception) { } // Okay
एक्सप्रेशन
एक्सप्रेशन के तौर पर इस्तेमाल किए जाने वाले if/else
कंडिशनल में यह हो सकता है
ब्रैकेट को सिर्फ़ तब छोड़ा जा सकता है, जब पूरा एक्सप्रेशन एक लाइन में फ़िट हो जाता हो.
val value = if (string.isEmpty()) 0 else 1 // Okay
val value = if (string.isEmpty()) // WRONG! 0 else 1
val value = if (string.isEmpty()) { // Okay 0 } else { 1 }
इंडेंट करना
जब भी कोई नया ब्लॉक या ब्लॉक जैसा कंस्ट्रक्शन खोला जाता है, तो इंडेंट में चार स्पेस बढ़ जाते हैं. ब्लॉक के खत्म होने पर, इंडेंट पिछले इंडेंट लेवल पर वापस आ जाता है. इंडेंट स्तर पूरे ब्लॉक में कोड और टिप्पणियों, दोनों पर लागू होता है.
हर लाइन में एक स्टेटमेंट
हर स्टेटमेंट के बाद एक लाइन ब्रेक होता है. अर्द्धविरामों का उपयोग नहीं किया जाता है.
लाइन रैपिंग
कोड में ज़्यादा से ज़्यादा 100 वर्ण हो सकते हैं. जैसा कि नीचे बताया गया है, उसे छोड़कर, इस सीमा को पार करने वाली किसी भी लाइन को लाइन-रैप किया जाना चाहिए, जैसा कि नीचे बताया गया है.
अपवाद:
- ऐसी लाइनें जिनमें कॉलम की सीमा का पालन नहीं किया जा सकता (उदाहरण के लिए, KDoc में एक लंबा URL)
package
औरimport
के स्टेटमेंट- किसी टिप्पणी में मौजूद कमांड लाइन, जिन्हें काटकर शेल में चिपकाया जा सकता है
कहां ब्रेक करें
लाइन रैपिंग का मुख्य निर्देश यह है कि: वाक्य की खास बातों को ध्यान में रखना चाहिए. साथ ही:
- जब किसी ऑपरेटर या इन्फ़िक्स फ़ंक्शन नाम पर कोई लाइन टूटती है, तो ब्रेक ऑपरेटर या इन्फ़िक्स फ़ंक्शन के नाम के बाद.
- जब इन “ऑपरेटर-जैसे” सिंबल पर कोई लाइन टूटती है, तो ब्रेक होता है
चिह्न से पहले आता है:
- बिंदु सेपरेटर (
.
,?.
). - सदस्य रेफ़रंस (
::
) के दो कोलन.
- बिंदु सेपरेटर (
- उस तरीके या कंस्ट्रक्टर का नाम, उस ओपन ब्रैकेट (
(
) में अटैच रहता है जो इसे फ़ॉलो करता है. - कॉमा (
,
), उससे पहले बने टोकन के साथ अटैच रहता है. - लैम्डा ऐरो (
->
), आर्ग्युमेंट सूची के पहले वाली सूची में अटैच रहता है.
फ़ंक्शन
जब फ़ंक्शन हस्ताक्षर एक लाइन में फ़िट न होता हो, तो हर पैरामीटर के एलान को उसकी लाइन में तोड़ दें. इस फ़ॉर्मैट में बताए गए पैरामीटर के लिए, सिर्फ़ एक इंडेंट (+4) का इस्तेमाल किया जाना चाहिए. क्लोज़िंग ब्रैकेट ()
) और रिटर्न टाइप, बिना किसी अतिरिक्त इंडेंट के अपनी ही लाइन में रखे जाते हैं.
fun <T> Iterable<T>.joinToString( separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "" ): String { // … }
एक्सप्रेशन फ़ंक्शन
जब किसी फ़ंक्शन में सिर्फ़ एक एक्सप्रेशन होता है, तो उसे एक्सप्रेशन फ़ंक्शन का इस्तेमाल करना चाहिए.
override fun toString(): String { return "Hey" }
override fun toString(): String = "Hey"
प्रॉपर्टी
जब कोई प्रॉपर्टी शुरू करने वाला टूल एक लाइन में फ़िट न हो, तो बराबर के निशान (=
) के बाद ब्रेक लें और इंडेंट का इस्तेमाल करें.
private val defaultCharset: Charset? = EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file)
get
और/या set
फ़ंक्शन का एलान करने वाली प्रॉपर्टी, दोनों को चालू करना चाहिए
सामान्य इंडेंट के साथ अपनी लाइन (+4). एक जैसे नियमों का इस्तेमाल करके, उन्हें फ़ॉर्मैट करें
का भी इस्तेमाल किया जा सकता है.
var directory: File? = null set(value) { // … }अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है रीड-ओनली प्रॉपर्टी में ऐसे छोटे सिंटैक्स का इस्तेमाल किया जा सकता है जो एक लाइन में फ़िट हो जाए.
val defaultExtension: String get() = "kt"
वाइटस्पेस
वर्टिकल
आपको एक खाली लाइन दिखेगी:
- क्लास के लगातार सदस्यों के बीच: प्रॉपर्टी, कंस्ट्रक्टर,
फ़ंक्शन, नेस्ट की गई क्लास वगैरह.
- अपवाद: दो खातों के बीच एक खाली लाइन लगातार चलने वाली प्रॉपर्टी (उनके बीच में कोई दूसरा कोड नहीं है) वैकल्पिक है. ऐसी खाली लाइनों का इस्तेमाल, ज़रूरत पड़ने पर प्रॉपर्टी के लॉजिकल ग्रुप बनाना और प्रॉपर्टी को जोड़ना साथ ही, बैकिंग प्रॉपर्टी भी शामिल करें.
- अपवाद: ईनम कॉन्सटेंट के बीच की खाली लाइनें कवर की गई हैं देखें.
- कोड को व्यवस्थित करने के लिए, ज़रूरत के हिसाब से स्टेटमेंट के बीच में सब-सेक्शन में बांट दिया गया है.
- वैकल्पिक रूप से किसी फ़ंक्शन में पहले स्टेटमेंट से पहले, क्लास के पहले सदस्य के पहले या किसी क्लास के आखिरी सदस्य के बाद क्लास (न तो प्रोत्साहित करें, न ही निराश करें).
- इस दस्तावेज़ के अन्य सेक्शन के मुताबिक (जैसे, स्ट्रक्चर सेक्शन).
लगातार कई खाली लाइनों की अनुमति है, लेकिन उन्हें बढ़ावा नहीं दिया जाता या की ज़रूरत नहीं पड़ेगी.
हॉरिज़ॉन्टल
भाषा या स्टाइल के अन्य नियमों के मुताबिक, ज़रूरत पड़ने पर और लिटरल, टिप्पणियों, और KDoc के अलावा, एक ASCII खाली जगह सिर्फ़ नीचे दी गई जगहों पर दिखती है:
- रिज़र्व किए गए किसी शब्द को अलग करना, जैसे कि
if
,for
याcatch
एक खुले कोष्ठक ((
) से जो उस पंक्ति पर उसके बाद आता है.// WRONG! for(i in 0..1) { }
// Okay for (i in 0..1) { }
- किसी भी रिज़र्व किए गए शब्द को अलग करना, जैसे कि
else
याcatch
को उस लाइन पर पहले से शुरू होने वाले कर्ली ब्रेस (}
) को बंद करना.// WRONG! }else { }
// Okay } else { }
-
किसी भी खुले कर्ली ब्रेस से पहले (
{
).// WRONG! if (list.isEmpty()){ }
// Okay if (list.isEmpty()) { }
-
किसी भी बाइनरी ऑपरेटर के दोनों ओर.
// WRONG! val two = 1+1
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है// Okay val two = 1 + 1
यह इन “ऑपरेटर-जैसे” प्रतीकों पर भी लागू होता है:- Lambda एक्सप्रेशन (
->
) में ऐरो.// WRONG! ints.map { value->value.toString() }
// Okay ints.map { value -> value.toString() }
-
सदस्य रेफ़रंस के दो कोलन (
::
).// WRONG! val toString = Any :: toString
// Okay val toString = Any::toString
-
डॉट सेपरेटर (
.
).// WRONG it . toString()
// Okay it.toString()
-
रेंज ऑपरेटर (
..
).// WRONG for (i in 1 .. 4) { print(i) }
// Okay for (i in 1..4) { print(i) }
- Lambda एक्सप्रेशन (
-
कोलन (
:
) से पहले सिर्फ़ अगर इसे तय करने के लिए क्लास की जानकारी में इस्तेमाल किया गया हो बेस क्लास या इंटरफ़ेस हो या जबwhere
क्लॉज़ का इस्तेमाल किया गया हो इसके लिए सामान्य पाबंदियां हैं.// WRONG! class Foo: Runnable
// Okay class Foo : Runnable
// WRONG fun <T: Comparable> max(a: T, b: T)
// Okay fun <T : Comparable> max(a: T, b: T)
// WRONG fun <T> max(a: T, b: T) where T: Comparable<T>
// Okay fun <T> max(a: T, b: T) where T : Comparable<T>
-
कॉमा (
,
) या कोलन (:
) के बाद.// WRONG! val oneAndTwo = listOf(1,2)
// Okay val oneAndTwo = listOf(1, 2)
// WRONG! class Foo :Runnable
// Okay class Foo : Runnable
-
डबल स्लैश (
//
) के दोनों ओर जो टिप्पणी. यहां, एक से ज़्यादा स्पेस का इस्तेमाल किया जा सकता है. हालांकि, यह ज़रूरी नहीं है.// WRONG! var debugging = false//disabled by default
// Okay var debugging = false // disabled by default
इस नियम को ज़रूरी या प्रतिबंधित नहीं माना जाता लाइन की शुरुआत या आखिर में अतिरिक्त जगह; यह सिर्फ़ अंदर की जगह.
खास कंस्ट्रक्ट
Enum क्लास
बिना फ़ंक्शन वाले और उसके कॉन्सटेंट पर कोई दस्तावेज़ न होने वाले ईनम को विकल्प के तौर पर एक लाइन में फ़ॉर्मैट किया जा सकता है.
enum class Answer { YES, NO, MAYBE }
जब किसी ईनम में कॉन्सटेंट को अलग-अलग लाइनों में रखा जाता है, तो उनके बीच खाली लाइन की ज़रूरत नहीं होती. सिर्फ़ ऐसे मामले में जहां वे किसी बॉडी को परिभाषित करते हैं.
enum class Answer { YES, NO, MAYBE { override fun toString() = """¯\_(ツ)_/¯""" } }
ईनम क्लास, क्लास होती हैं. इसलिए, क्लास को फ़ॉर्मैट करने के दूसरे सभी नियम लागू होते हैं.
एनोटेशन
एनोटेट किए गए कंस्ट्रक्शन के ठीक पहले, सदस्य या टाइप के एनोटेशन को अलग-अलग लाइन में रखा जाता है.
@Retention(SOURCE) @Target(FUNCTION, PROPERTY_SETTER, FIELD) annotation class Global
बिना आर्ग्युमेंट के एनोटेशन को एक लाइन में रखा जा सकता है.
@JvmField @Volatile var disposable: Disposable? = null
जब बिना आर्ग्युमेंट वाला सिर्फ़ एक एनोटेशन मौजूद हो, तो इसे एलान वाली लाइन में रखा जा सकता है.
@Volatile var disposable: Disposable? = null @Test fun selectAll() { // … }
@[...]
सिंटैक्स का इस्तेमाल सिर्फ़ साइट के किसी खास टारगेट के साथ किया जा सकता है. ऐसा सिर्फ़
एक लाइन में बिना आर्ग्युमेंट के दो या उससे ज़्यादा एनोटेशन को मिलाया जा सकता है.
@field:[JvmStatic Volatile] var disposable: Disposable? = null
इंप्लिसिट रिटर्न/प्रॉपर्टी टाइप
अगर किसी एक्सप्रेशन फ़ंक्शन का मुख्य हिस्सा या प्रॉपर्टी शुरू करने वाला टूल एक अदिश है मान या रिटर्न टाइप का मुख्य भाग से साफ़ तौर पर अनुमान लगाया जा सकता है. इसके बाद, छोड़ा जा सकता है.
override fun toString(): String = "Hey" // becomes override fun toString() = "Hey"
private val ICON: Icon = IconLoader.getIcon("/icons/kotlin.png") // becomes private val ICON = IconLoader.getIcon("/icons/kotlin.png")
लाइब्रेरी लिखते समय, स् पष्ट प्रकार की घोषणा को बनाए रखें जब यह सार्वजनिक एपीआई का हिस्सा है.
इन्हें
आइडेंटिफ़ायर सिर्फ़ ASCII अक्षरों और अंकों का इस्तेमाल करते हैं. साथ ही, यहां दिए गए कुछ मामलों में, अंडरस्कोर इस्तेमाल किए जाते हैं. इसलिए, हर मान्य आइडेंटिफ़ायर के नाम का मिलान रेगुलर एक्सप्रेशन \w+
से किया जाता है.
खास प्रीफ़िक्स या सफ़िक्स, जैसे कि उदाहरणों में बताया गया है
name_
, mName
, s_name
, और kName
का इस्तेमाल, सिर्फ़ इन मामलों में नहीं किया जाता
बैकिंग प्रॉपर्टी (देखें
बैकिंग प्रॉपर्टी).
पैकेज के नाम
पैकेज के नाम अंग्रेज़ी के छोटे अक्षरों में हैं. इनमें एक के बाद एक शब्द शामिल हो सकते हैं एक साथ जोड़ा जा सकता है (कोई अंडरस्कोर नहीं).
// Okay package com.example.deepspace // WRONG! package com.example.deepSpace // WRONG! package com.example.deep_space
नाम लिखें
क्लास के नाम PascalCase में लिखे जाते हैं और आम तौर पर, संज्ञा या संज्ञा होते हैं
वाक्यांश शामिल हैं. उदाहरण के लिए, Character
या ImmutableList
. इंटरफ़ेस के नाम
संज्ञा या संज्ञा वाक्यांश भी होना चाहिए (जैसे, List
), लेकिन
कभी-कभी विशेषण या विशेषण वाक्यांश हो सकते हैं
(उदाहरण के लिए Readable
).
टेस्ट क्लास के नाम, उस क्लास के नाम से शुरू होते हैं जिसकी वे जांच कर रहे हैं.
और Test
पर खत्म होता है. उदाहरण के लिए, HashTest
या
HashIntegrationTest
.
फ़ंक्शन के नाम
फ़ंक्शन के नाम CamlCase में लिखे जाते हैं और आम तौर पर, क्रिया या क्रिया के वाक्यांश होते हैं. उदाहरण के लिए, sendMessage
या stop
.
नाम के लॉजिकल कॉम्पोनेंट को अलग करने के लिए, अंडरस्कोर को टेस्ट फ़ंक्शन के नामों में दिखाने की अनुमति है.
@Test fun pop_emptyStack() { // … }
@Composable
के साथ एनोटेट किए गए फ़ंक्शन जो Unit
दिखाते हैं, PascalCased हैं और उन्हें संज्ञा के तौर पर नाम दिया गया है, जैसे कि वे एक तरह के हों.
@Composable fun NameTag(name: String) { // … }
फ़ंक्शन के नाम के बीच खाली जगह नहीं होनी चाहिए, क्योंकि यह हर (खास तौर पर, यह Android पर पूरी तरह से काम नहीं करता है).
// WRONG! fun `test every possible case`() {} // OK fun testEveryPossibleCase() {}
लगातार नाम
हमेशा के लिए नाम, फ़ॉन्ट के सभी बड़े अक्षरों का इस्तेमाल करते हैं: अंडरस्कोर से अलग किए गए शब्दों का इस्तेमाल करें. लेकिन, असल में कॉन्स्टेंट क्या है?
कॉन्स्टेंट val
प्रॉपर्टी होती हैं, जिनमें कस्टम get
फ़ंक्शन नहीं होता है. इनका कॉन्टेंट
जो पूरी तरह से नहीं बदली जा सकती हों. साथ ही, इनके फ़ंक्शन का कोई खराब असर न हो. यह
इसमें नहीं बदले जा सकने वाले टाइप और नहीं बदले जा सकने वाले कलेक्शन शामिल हैं
और साथ ही स्केलर और स्ट्रिंग, अगर const
के रूप में चिह्नित हैं. अगर उपयोगकर्ता की गतिविधि
मॉनिटर की जा सकने वाली स्थिति बदल सकती है, वह स्थायी नहीं होती. सिर्फ़ इसके लिए
ऑब्जेक्ट को कभी म्यूट नहीं करना काफ़ी नहीं है.
const val NUMBER = 5 val NAMES = listOf("Alice", "Bob") val AGES = mapOf("Alice" to 35, "Bob" to 32) val COMMA_JOINER = Joiner.on(',') // Joiner is immutable val EMPTY_ARRAY = arrayOf()
ये नाम आम तौर पर संज्ञा या संज्ञा वाक्यांश होते हैं.
कॉन्स्टेंट वैल्यू सिर्फ़ object
में तय की जा सकती हैं
या टॉप लेवल एलान के तौर पर सबमिट करें. वे वैल्यू जो किसी ज़रूरी शर्त को पूरा करती हैं
class
के अंदर स्थिर है, लेकिन एक स्थिर नाम का इस्तेमाल किया जाना चाहिए.
अदिश मान वाले नियतांकों को const
का उपयोग करना चाहिए
मॉडिफ़ायर का इस्तेमाल करें.
एक जैसे नाम नहीं देने वाले
नॉन-कॉन्सटेंट नाम कैमलकेस में लिखे जाते हैं. ये इंस्टेंस प्रॉपर्टी, लोकल प्रॉपर्टी, और पैरामीटर के नामों पर लागू होते हैं.
val variable = "var" val nonConstScalar = "non-const" val mutableCollection: MutableSet= HashSet() val mutableElements = listOf(mutableInstance) val mutableValues = mapOf("Alice" to mutableInstance, "Bob" to mutableInstance2) val logger = Logger.getLogger(MyClass::class.java.name) val nonEmptyArray = arrayOf("these", "can", "change")
ये नाम आम तौर पर संज्ञा या संज्ञा वाक्यांश होते हैं.
बैकिंग प्रॉपर्टी
जब बैकिंग प्रॉपर्टी आवश्यक है, तो इसका नाम वास्तविक प्रॉपर्टी से पूरी तरह मेल खाना चाहिए यह अंडरस्कोर से पहले लगा होता है.
private var _table: Map? = null val table: Map get() { if (_table == null) { _table = HashMap() } return _table ?: throw AssertionError() }
वैरिएबल के नाम टाइप करें
हर टाइप वैरिएबल को किसी एक स्टाइल में नाम दिया जाता है:
- एक कैपिटल लेटर के बाद, वैकल्पिक तौर पर
एक अंक (जैसे,
E
,T
,X
,T2
) - क्लास के लिए इस्तेमाल किया जाने वाला नाम और इसके बाद कैपिटल लेटर का इस्तेमाल
अक्षर
T
(जैसे किRequestT
,FooBarT
)
ऊंटों का केस
कभी-कभी अंग्रेज़ी के किसी वाक्यांश को ऊंट में बदलने के एक से ज़्यादा सही तरीके होते हैं. उदाहरण के लिए, जब शॉर्ट फ़ॉर्म वाले शब्द या “IPv6” या “iOS” जैसे असामान्य स्ट्रक्चर मौजूद हों. अनुमान लगाने की संभावना बढ़ाने के लिए, नीचे दिए गए स्कीम का इस्तेमाल करें.
नाम के प्रोज़ रूप से शुरू करना:
- वाक्यांश को सामान्य ASCII में बदलें और सभी अपॉस्ट्रफ़ी हटाएं. उदाहरण के लिए, “म्युलर का एल्गोरिदम” “मुअलर्स एल्गोरिदम” बन सकता है.
- इस नतीजे को शब्दों में बांटें. फिर, इसे खाली जगह और बचे हुए विराम चिह्न (आम तौर पर, हाइफ़न) में बांट दें. इसका सुझाव दिया जाता है: अगर किसी शब्द का इस्तेमाल पहले से ही, सामान्य तरीके से ऊंट के केस के तौर पर किया गया है, तो उसे अलग-अलग हिस्सों में बांट दें (उदाहरण के लिए, “AdWords”, “विज्ञापन शब्द” बन जाता है. ध्यान दें कि “iOS” जैसे शब्द का मतलब ऊँट के केस में नहीं है; यह किसी भी कन्वेंशन का उल्लंघन करता है. इसलिए, यह सुझाव लागू नहीं होता.
- अब हर चीज़ को छोटे अक्षरों में लिखें (इसमें शॉर्ट फ़ॉर्म भी शामिल हैं). इसके बाद, इनमें से कोई एक काम करें:
- पास्कल केस पाने के लिए, हर शब्द के पहले वर्ण को अपरकेस में बदलें.
- पाने वाले पहले वर्ण को छोड़कर, हर शब्द के पहले वर्ण को अपरकेस में रखें ऊंट का केस.
- आखिर में, सभी शब्दों को एक आइडेंटिफ़ायर में जोड़ें.
ध्यान दें कि मूल शब्दों के केसिंग को करीब-करीब अनदेखा कर दिया गया है.
प्रोज़ फ़ॉर्म | सही | गलत |
---|---|---|
"एक्सएमएल Http अनुरोध" | XmlHttpRequest |
XMLHTTPRequest |
"नया ग्राहक आईडी" | newCustomerId |
newCustomerID |
"अंदरूनी स्टॉपवॉच" | innerStopwatch |
innerStopWatch |
"iOS पर IPv6 काम करता है" | supportsIpv6OnIos |
supportsIPv6OnIOS |
"YouTube इंपोर्टर" | YouTubeImporter |
YoutubeImporter * |
(* मान्य, लेकिन सुझाया नहीं गया.)
दस्तावेज़
फ़ॉर्मैटिंग
KDoc ब्लॉक की बुनियादी फ़ॉर्मैटिंग इस उदाहरण में देखी गई है:
/** * Multiple lines of KDoc text are written here, * wrapped normally… */ fun method(arg: String) { // … }
...या एक लाइन वाले इस उदाहरण में:
/** An especially short bit of KDoc. */
बुनियादी फ़ॉर्म हमेशा स्वीकार किया जाता है. एक लाइन वाला फ़ॉर्म
KDoc ब्लॉक (टिप्पणी मार्कर के साथ) की पूरी प्रोसेस के दौरान विकल्प के तौर पर इस्तेमाल किया जाना चाहिए
एक लाइन में फ़िट हो सकता है. ध्यान दें कि यह सिर्फ़ तब लागू होता है, जब
@return
जैसे टैग को ब्लॉक करें.
पैराग्राफ़
एक खाली लाइन—यानी, ऐसी लाइन जिसमें सिर्फ़ आगे अलाइन किया गया तारे का निशान हो
(*
)—पैराग्राफ़ के बीच में दिखता है. साथ ही, मौजूद होने पर ब्लॉक टैग के ग्रुप से पहले दिखता है.
टैग ब्लॉक करें
इस्तेमाल किए गए कोई भी स्टैंडर्ड “ब्लॉक टैग” क्रम में दिखते हैं
@constructor
, @receiver
, @param
, @property
, @return
,
@throws
, @see
, और ये कभी भी खाली ब्यौरे के साथ नहीं दिखते.
जब कोई ब्लॉक टैग एक लाइन में फ़िट नहीं होता,
अगला कॉलम, @
की पोज़िशन से चार स्पेस तक इंडेंट किया गया है.
खास जानकारी वाला फ़्रैगमेंट
हर KDoc ब्लॉक की शुरुआत में खास जानकारी के एक छोटे हिस्से से शुरुआत होती है. यह खंड है बहुत महत्वपूर्ण: यह केवल टेक्स्ट का वह हिस्सा है जो कुछ कॉन्टेक्स्ट में इस्तेमाल किया जा सकता है. जैसे, क्लास और मेथड इंडेक्स.
यह एक फ़्रैगमेंट है–संज्ञा वाला वाक्यांश या क्रिया वाला वाक्यांश है, पूरा वाक्य नहीं.
यह "A `Foo` is a...
" से शुरू नहीं होता,
या "This method returns...
",
न ही इसे पूरा इंपेरेटिव वाक्य बनाने की ज़रूरत है, जैसे कि
"Save the record.
". हालांकि, फ़्रैगमेंट कैपिटल लेटर में है और
इसमें विराम चिह्न भी लगाया गया था, जैसे कि यह एक पूरा वाक्य था.
इस्तेमाल
कम से कम, हर public
टाइप के लिए KDoc मौजूद होना चाहिए,
और इस तरह के हर public
या protected
सदस्य को
इसके कुछ अपवाद हैं.
अपवाद: जानकारी देने वाले फ़ंक्शन
getFoo
जैसे "आसान" फ़ंक्शन के लिए KDoc ज़रूरी नहीं है
और foo
जैसी प्रॉपर्टी के ऐसे मामलों में जहां सच में और असल में कुछ और ही मददगार हो सकता है, जैसे कि "सिर्फ़ "लौटता है".
इस अपवाद का हवाला देना सही नहीं है, क्योंकि यह ज़रूरी नहीं है कि
जो एक सामान्य पाठक के लिए ज़रूरी है. उदाहरण के लिए,
getCanonicalName
नाम का फ़ंक्शन या canonicalName
नाम की प्रॉपर्टी,
अपने दस्तावेज़ों को अनदेखा न करें (इस तर्क के साथ यह बताया गया है कि
/** Returns the canonical name. */
) से पता चलता है कि किसी सामान्य पाठक के पास
"कैननिकल नाम" शब्द क्या हो इसका मतलब है!
अपवाद: ओवरराइड
KDoc हमेशा किसी ऐसे तरीके पर मौजूद नहीं होता जो सुपरटाइप तरीके को बदल देता हो.