دليل أسلوب Kotlin

يمثل هذا المستند التعريف الكامل لمعايير ترميز Android من Google لرمز المصدر في لغة برمجة Kotlin. يتم وصف ملف مصدر Kotlin بأنه بتنسيق نمط Android من Google في حال الالتزام بالقواعد الواردة هنا فقط.

مثل أدلة أسلوب البرمجة الأخرى، فإن المشكلات لم تغطي فقط المشكلات الجمالية للتنسيق، ولكن أنواعًا أخرى من الاصطلاحات أو معايير البرمجة أيضًا. ومع ذلك، فإن هذا المستند يركز بشكل أساسي على القواعد الدقيقة التي نتبعها عالميًا، ويتجنب تقديم النصائح غير القابلة للتنفيذ بشكل واضح (سواء كان ذلك عن طريق بشري أو أداة).

تاريخ التعديل الأخير: 06/09/2023

الملفات المصدر

ويجب ترميز كل الملفات المصدر بترميز 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 (0×20) هو حرف المسافة البيضاء الوحيد الذي يظهر في أي مكان في ملف المصدر. وهذا يعني ما يلي:

  • يتم تخطي جميع حروف المسافات البيضاء الأخرى في السلسلة والأحرف الحرفية.
  • لا تُستخدم أحرف Tab لإضافة المسافة البادئة.

تسلسلات الهروب الخاصة

لأي حرف له تسلسل إلغاء خاص (\b و\n و\r و\t و\' و\" و\\ و\$)، يُستخدم ذلك التسلسل بدلاً من رمز يونيكود المقابل (مثال: \u000a).

أحرف بتنسيق غير ASCII

وبالنسبة إلى الأحرف المتبقية غير ASCII، يمكن إما استخدام حرف Unicode الفعلي (مثال: ) أو إلغاء يونيكود مكافئ (مثل، \u221e). يعتمد الخيار فقط على العلامة التي تصنع الرمز من السهل قراءتها وفهمها لا يُنصح باستخدام أحرف Unicode القابلة للطباعة في أي مكان لا يُنصح باستخدامها خارج نطاق القيم الحرفية للسلسلة والتعليقات.

مثال مناقشة
val unitAbbrev = "μs" الأفضل: واضحة تمامًا حتى بدون تعليق.
val unitAbbrev = "\u03bcs" // μs سيء: ليس هناك سبب لاستخدام حرف الإلغاء مع حرف قابل للطباعة.
val unitAbbrev = "\u03bcs" رديء: ليس لدى القارئ أي فكرة عن مضمونه.
return "\ufeff" + content جيد: استخدم رموز الإلغاء للأحرف غير القابلة للطباعة، وعلّق إذا لزم الأمر.

البنية

يضم ملف .kt ما يلي بالترتيب:

  • عنوان حقوق الطبع والنشر و/أو الترخيص (اختياري)
  • تعليقات توضيحية على مستوى الملف
  • بيان الحزمة
  • عبارات الاستيراد
  • نماذج البيانات ذات المستوى الأعلى

يفصل سطر واحد فارغ كل قسم من هذه الأقسام.

إذا كان عنوان حقوق الطبع والنشر أو الترخيص ينتمي إلى الملف، يجب وضعه في أعلى يسار التعليق في تعليق متعدد الأسطر.

/*
 * Copyright 2017 Google, Inc.
 *
 * ...
 */
 

عدم استخدام نمط KDoc أو تعليق مؤلف من سطر واحد.

/**
 * Copyright 2017 Google, Inc.
 *
 * ...
 */
// Copyright 2017 Google, Inc.
//
// ...

تعليقات توضيحية على مستوى الملف

التعليقات التوضيحية التي تحتوي على "file" استخدام الموقع المستهدَف يتم وضعها بين أي تعليق رأس وإعلان الحزمة.

بيان الحزمة

لا تخضع جملة الحزمة لأي حد من الأعمدة ولا يتم التفافها مطلقًا.

عبارات الاستيراد

يتم تجميع عبارات الاستيراد للفئات والدوال والخصائص معًا في قائمة واحدة وترتيب ASCII.

غير مسموح بعمليات استيراد أحرف البدل (من أي نوع).

على غرار عبارة package، لا تخضع عبارات الاستيراد حد العمود ولا يتم التفافها سطرًا أبدًا.

نماذج البيانات ذات المستوى الأعلى

يمكن أن يحدّد ملف .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)
}

الوحدات غير الفارغة

تعتمد الدعامات على أسلوب "كيرنيغان" و"ريتشي" ("الأقواس المصرية") من أجل الكتل غير الفارغة والتركيبات المشابهة للكتلة:

  • ليس هناك فاصل أسطر قبل القوس الافتتاحي.
  • فاصل سطر بعد القوس الافتتاحي.
  • فاصل سطر قبل قوس الإغلاق.
  • فاصل سطر بعد قوس الإغلاق، فقط إذا كان هذا القوس يُنهي عبارة أو إنهاء نص دالة أو دالة إنشاء أو فئة مُسمّاة. على سبيل المثال، لا يوجد فاصل أسطر بعد القوس المعقوف إذا كان متبوعًا 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 حرف. باستثناء ما هو موضح أدناه، يجب أن يتم التفاف أي سطر يتجاوز هذا الحد، كما هو موضح أدناه.

الاستثناءات:

  • الأسطر التي يتعذر فيها الالتزام بحد الأعمدة (على سبيل المثال، عنوان URL طويل في KDoc)
  • كشف حساب package وimport
  • سطور الأوامر في تعليق قد يتم قصها ولصقها في واجهة أوامر

أماكن العُطل

التوجيه الأساسي لإحاطة الأسطر هو: تفضيل التقسيم على مستوى نحوي أعلى. أيضًا:

  • عندما يتم كسر سطر عند عامل تشغيل أو يتم التعويض عن اسم الدالة، يأتي الفاصل بعد عامل التشغيل أو infix اسم الدالة.
  • عند كسر خط عند الرموز التالية التي تشبه "عامل التشغيل"، فإن الفاصل قبل الرمز:
    • فاصل النقاط (.، ?.).
    • النقطتان في مرجع عضو (::).
  • تظل الطريقة أو اسم الدالة الإنشائية مرفقة بالقوس المفتوح (() الذي ويتابعها.
  • تظل الفاصلة (,) مرتبطة بالرمز المميّز الذي يسبقه.
  • يظل سهم lambda (->) مرفقًا بقائمة الوسيطات التي تسبقه.

الدوال

في حال عدم توافق توقيع دالة مع سطر واحد، يمكنك تقسيم بيان كل مَعلمة إلى سطر منفصل. ويجب أن تستخدِم المَعلمات المحدّدة بهذا التنسيق مسافة بادئة واحدة (+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)
      }
      
  • قبل النقطتين (:) فقط إذا تم استخدامها في تصريح الفئة لتحديد فئة أساسية أو واجهات، أو عند استخدامها في بند 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 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() {}

الأسماء الثابتة

تستخدم الأسماء الثابتة OFFER_SNAKE_CASE: تكون جميع الأحرف الكبيرة والصغيرة. مع فصل الكلمات بشرطات سفلية. ولكن ما هو الثابت بالضبط؟

الثوابت هي سمات 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 للقيم العددية المعدِّل.

الأسماء غير الثابتة

تُكتب الأسماء غير الثابتة بأحرف CamlCase. تنطبق هذه الإعدادات على سمات المثيل والخصائص المحلية وأسماء المَعلمات.

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<String, Int>? = null

val table: Map<String, Int>
    get() {
        if (_table == null) {
            _table = HashMap()
        }
        return _table ?: throw AssertionError()
    }

كتابة أسماء المتغيرات

تتم تسمية كل متغير من النوع بأحد نمطين:

  • حرف كبير واحد، متبوعًا اختياريًا رقم مفرد (مثل E، T، X، T2)
  • اسم في النموذج المستخدم للفئات، متبوعًا برأس المال الحرف T (مثلاً RequestT، FooBarT)

حالة الجمل

في بعض الأحيان، تتوفّر أكثر من طريقة معقولة لتحويل عبارة باللغة الإنجليزية إلى حالة جمل، كما هو الحال عند استخدام اختصارات أو بُنى غير عادية مثل "IPv6" أو "iOS". لتحسين إمكانية التنبؤ، استخدم المخطط التالي.

يبدأ بالصيغة النثرية للاسم:

  1. حوِّل العبارة إلى ASCII عادي وأزِل الفاصلات العليا. على سبيل المثال، قد تصبح "خوارزمية مولر" "خوارزمية ميولر".
  2. قسّم هذه النتيجة إلى كلمات، مع تقسيمها على مسافات وأي علامات ترقيم متبقية (عادةً واصلات). إجراء مقترَح: إذا كان هناك أي كلمة لها مظهر تقليدي لحالة الجمل في الاستخدام الشائع، قسِّم هذا العنصر إلى الأجزاء المكوّنة لها (على سبيل المثال، وتصبح "AdWords" هي "كلمات إعلانية"). يُرجى ملاحظة أنّ كلمة مثل "iOS" ليست في حد ذاتها جملة في حد ذاتها. تتحدى أي اصطلاح، لذا لا تنطبق هذه التوصية.
  3. الآن بأحرف صغيرة (بما في ذلك الاختصارات)، ثم قم بأحد الإجراءات التالية:
    • يجب أن يكون الحرف الأول من كل كلمة كبيرًا لعرض حالة باسكال.
    • يجب أن يكون الحرف الأول من كل كلمة كبيرًا ما عدا الحرف الأول الذي ينتج عنه حالة الجمل.
  4. وأخيرًا، اجمع كل الكلمات في معرّف واحد.

يُرجى العِلم أنّه يتم تقريبًا تجاهل حالة الكلمات الأصلية.

صيغة نثرية صحيح غير صحيح
"طلب XML Http" XmlHttpRequest XMLHTTPRequest
"الرقم التعريفي للعميل الجديد" newCustomerId newCustomerID
"ساعة إيقاف داخلية" innerStopwatch innerStopWatch
"يتوافق مع IPv6 على iOS" 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 وهذان العنصران أبدًا مع وصف فارغ. في حال عدم احتواء علامة الحظر على سطر واحد تم وضع مسافة بادئة إلى 4 مسافات بين أسطر المتابعة بمقدار 4 مسافات من موضع @.

جزء الملخّص

تبدأ كل مجموعة KDoc بجزء ملخص موجز. هذا الجزء هو مهم للغاية: إنه الجزء الوحيد الذي يظهر من النص في سياقات معينة مثل فهارس الفئات والطريقة.

ويكون الجزء عبارة عن جملة اسمية أو فعل، وليست جملة كاملة. ولا يبدأ بـ "A `Foo` is a..."، أو "This method returns..."، ولا يتعين عليها تشكيل جملة ضرورية كاملة مثل "Save the record.". ومع ذلك، يكون الجزء كبيرًا ترقيمها كما لو كانت جملة كاملة.

الاستخدام

على الأقل، يتوفر KDoc لكل نوع من أنواع public، وكل عضو public أو protected من هذا النوع، مع بعض الاستثناءات المذكورة أدناه.

استثناء: الدوال الشرح الذاتي

إنّ KDoc اختياري للدوال "البسيطة والواضحة" مثل getFoo. ومواقع مثل foo، في الحالات التي لا يوجد فيها أي شيء جدير بالاهتمام حقًا سوى "عرض كرة القدم".

وليس من المناسب الاستشهاد بهذا الاستثناء لتبرير إغفال حذف النصوص ذات الصلة المعلومات التي قد يحتاج القارئ العادي إلى معرفتها. على سبيل المثال، بالنسبة إلى دالة اسمها getCanonicalName أو خاصية باسم canonicalName، لا تحذف وثائقه (مع المبرر المنطقي أنها ستذكر فقط /** Returns the canonical name. */) إذا كان القارئ العادي قد لا يكون لديه فكرة عن مصطلح "الاسم المتعارف عليه" يعني!

استثناء: عمليات الإلغاء

لا تتوفّر KDoc دائمًا في طريقة تلغي طريقة النمط الفائق.