কোটলিন শৈলী গাইড

এই নথিটি কোটলিন প্রোগ্রামিং ভাষার সোর্স কোডের জন্য Google-এর অ্যান্ড্রয়েড কোডিং মানগুলির সম্পূর্ণ সংজ্ঞা হিসাবে কাজ করে৷ একটি Kotlin সোর্স ফাইলকে Google Android স্টাইলে বলে বর্ণনা করা হয়েছে যদি এবং শুধুমাত্র যদি এটি এখানে নিয়ম মেনে চলে।

অন্যান্য প্রোগ্রামিং স্টাইল গাইডের মতো, সমস্যাগুলি কেবল বিন্যাসের নান্দনিক সমস্যাগুলিই নয়, অন্যান্য ধরণের কনভেনশন বা কোডিং মানকেও অন্তর্ভুক্ত করে। যাইহোক, এই দস্তাবেজটি প্রাথমিকভাবে কঠোর এবং দ্রুত নিয়মগুলির উপর ফোকাস করে যা আমরা সর্বজনীনভাবে অনুসরণ করি এবং এমন পরামর্শ দেওয়া এড়িয়ে যায় যা স্পষ্টভাবে প্রয়োগযোগ্য নয় (মানুষ বা হাতিয়ার দ্বারা হোক না কেন)।

শেষ আপডেট: 2023-09-06

উৎস ফাইল

সমস্ত উৎস ফাইল UTF-8 হিসাবে এনকোড করা আবশ্যক।

নামকরণ

যদি একটি উৎস ফাইলে শুধুমাত্র একটি একক শীর্ষ-স্তরের শ্রেণী থাকে, তাহলে ফাইলের নামটি কেস-সংবেদনশীল নাম এবং .kt এক্সটেনশন প্রতিফলিত করা উচিত। অন্যথায়, যদি একটি সোর্স ফাইলে একাধিক শীর্ষ-স্তরের ঘোষণা থাকে, তাহলে ফাইলের বিষয়বস্তু বর্ণনা করে এমন একটি নাম বেছে নিন, PascalCase প্রয়োগ করুন (ফাইলের নামটি বহুবচন হলে ক্যামেলকেস গ্রহণযোগ্য), এবং .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 ভাল: অ-মুদ্রণযোগ্য অক্ষরের জন্য এস্কেপ ব্যবহার করুন এবং প্রয়োজনে মন্তব্য করুন।

গঠন

A .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)
}

অ-খালি ব্লক

বন্ধনীগুলি কার্নিঘান এবং রিচি শৈলী ("মিশরীয় বন্ধনী") অনুসরণ করে খালি ব্লক এবং ব্লকের মতো নির্মাণের জন্য:

  • ওপেনিং ব্রেসের আগে কোন লাইন ব্রেক নেই।
  • ওপেনিং ব্রেসের পর লাইন ব্রেক।
  • বন্ধ বন্ধনী আগে লাইন বিরতি.
  • ক্লোজিং ব্রেসের পরে লাইন ব্রেক, শুধুমাত্র যদি সেই ব্রেসটি কোনো স্টেটমেন্ট বন্ধ করে দেয় বা কোনো ফাংশন, কনস্ট্রাক্টর বা নামকৃত ক্লাসের বডি বন্ধ করে দেয়। উদাহরণস্বরূপ, ব্রেসের পরে কোন লাইন বিরতি নেই যদি এটি 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()
        }
    }
}

enum ক্লাসের জন্য কয়েকটি ব্যতিক্রম নীচে দেওয়া হল।

খালি ব্লক

একটি খালি ব্লক বা ব্লকের মতো নির্মাণ অবশ্যই 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"

হোয়াইটস্পেস

উল্লম্ব

একটি একক ফাঁকা লাইন প্রদর্শিত হবে:

  • একটি শ্রেণীর ক্রমাগত সদস্যদের মধ্যে : বৈশিষ্ট্য, নির্মাণকারী, ফাংশন, নেস্টেড ক্লাস, ইত্যাদি।
    • ব্যতিক্রম: পরপর দুটি বৈশিষ্ট্যের মধ্যে একটি ফাঁকা লাইন (তাদের মধ্যে অন্য কোনো কোড নেই) ঐচ্ছিক। এই ধরনের ফাঁকা লাইনগুলি প্রয়োজন অনুসারে বৈশিষ্ট্যগুলির যৌক্তিক গ্রুপিং তৈরি করতে এবং তাদের ব্যাকিং সম্পত্তির সাথে বৈশিষ্ট্য যুক্ত করতে ব্যবহৃত হয়, যদি উপস্থিত থাকে।
    • ব্যতিক্রম: enum ধ্রুবকগুলির মধ্যে ফাঁকা রেখাগুলি নীচে কভার করা হয়েছে।
  • বিবৃতিগুলির মধ্যে, কোডটিকে যৌক্তিক উপধারায় সংগঠিত করার জন্য প্রয়োজন
  • ঐচ্ছিকভাবে একটি ফাংশনে প্রথম বিবৃতির আগে, একটি ক্লাসের প্রথম সদস্যের আগে, বা একটি ক্লাসের শেষ সদস্যের পরে (উৎসাহিত বা নিরুৎসাহিত করা হয় না)।
  • এই নথির অন্যান্য বিভাগগুলির জন্য প্রয়োজনীয় (যেমন কাঠামো বিভাগ)।

একাধিক ক্রমাগত ফাঁকা লাইন অনুমোদিত, কিন্তু উত্সাহিত বা কখনও প্রয়োজন হয় না।

অনুভূমিক

ভাষা বা অন্যান্য শৈলীর নিয়মের প্রয়োজনের বাইরে, এবং আক্ষরিক, মন্তব্য এবং 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
    এটি নিম্নলিখিত "অপারেটর-মত" চিহ্নগুলির ক্ষেত্রেও প্রযোজ্য:
    • একটি ল্যাম্বডা এক্সপ্রেশনে তীর ( -> )।
      // 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 এবং এর ধ্রুবকগুলিতে কোন ডকুমেন্টেশন ঐচ্ছিকভাবে একটি একক লাইন হিসাবে ফর্ম্যাট করা যেতে পারে।

enum class Answer { YES, NO, MAYBE }

যখন একটি enum-এর ধ্রুবকগুলিকে পৃথক লাইনে স্থাপন করা হয়, তখন তাদের মধ্যে একটি ফাঁকা রেখার প্রয়োজন হয় না শুধুমাত্র যে ক্ষেত্রে তারা একটি বডিকে সংজ্ঞায়িত করে।

enum class Answer {
    YES,
    NO,

    MAYBE {
        override fun toString() = """¯\_(ツ)_/¯"""
    }
}

যেহেতু enum ক্লাসগুলি ক্লাস, তাই ক্লাস ফর্ম্যাট করার জন্য অন্যান্য সমস্ত নিয়ম প্রযোজ্য।

টীকা

সদস্য বা টাইপ টীকাগুলি টীকা তৈরির ঠিক আগে আলাদা লাইনে স্থাপন করা হয়।

@Retention(SOURCE)
@Target(FUNCTION, PROPERTY_SETTER, FIELD)
annotation class Global

আর্গুমেন্ট ছাড়া টীকা এক লাইনে স্থাপন করা যেতে পারে।

@JvmField @Volatile
var disposable: Disposable? = null

যখন যুক্তি ছাড়া শুধুমাত্র একটি একক টীকা উপস্থিত থাকে, তখন এটি ঘোষণার মতো একই লাইনে স্থাপন করা যেতে পারে।

@Volatile var disposable: Disposable? = null

@Test fun selectAll() {
    // …
}

@[...] সিনট্যাক্স শুধুমাত্র একটি সুস্পষ্ট ব্যবহার-সাইট টার্গেটের সাথে ব্যবহার করা যেতে পারে, এবং শুধুমাত্র একটি লাইনে আর্গুমেন্ট ছাড়া 2 বা তার বেশি টীকা একত্রিত করার জন্য।

@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")

একটি লাইব্রেরি লেখার সময়, যখন এটি সর্বজনীন API-এর অংশ হয় তখন স্পষ্ট টাইপ ঘোষণা বজায় রাখুন।

নামকরণ

শনাক্তকারীরা শুধুমাত্র 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

ফাংশনের নাম

ফাংশনের নামগুলি ক্যামেলকেসে লেখা হয় এবং সাধারণত ক্রিয়া বা ক্রিয়া বাক্যাংশ। উদাহরণস্বরূপ, sendMessage বা stop

নামের যৌক্তিক উপাদানগুলিকে আলাদা করার জন্য পরীক্ষার ফাংশনের নামগুলিতে আন্ডারস্কোরগুলি উপস্থিত হওয়ার অনুমতি দেওয়া হয়।

@Test fun pop_emptyStack() {
    // …
}

@Composable যে রিটার্ন Unit সাথে টীকা করা ফাংশনগুলি PascalCased এবং বিশেষ্য হিসাবে নামকরণ করা হয়, যেন সেগুলি প্রকার।

@Composable
fun NameTag(name: String) {
    // …
}

ফাংশনের নামগুলিতে স্পেস থাকা উচিত নয় কারণ এটি প্রতিটি প্ল্যাটফর্মে সমর্থিত নয় (উল্লেখ্যভাবে, এটি অ্যান্ড্রয়েডে সম্পূর্ণরূপে সমর্থিত নয়)।

// WRONG!
fun `test every possible case`() {}
// OK
fun testEveryPossibleCase() {}

ধ্রুবক নাম

ধ্রুবক নামগুলি UPPER_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 মডিফায়ার ব্যবহার করবে।

অ ধ্রুবক নাম

অ-ধ্রুবক নামগুলি ক্যামেলকেসে লেখা হয়। এগুলি উদাহরণ বৈশিষ্ট্য, স্থানীয় বৈশিষ্ট্য এবং পরামিতি নামের ক্ষেত্রে প্রযোজ্য।

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. অবশেষে, একটি একক শনাক্তকারীতে সমস্ত শব্দ যোগ করুন।

উল্লেখ্য যে মূল শব্দের আবরণ প্রায় সম্পূর্ণরূপে উপেক্ষা করা হয়।

গদ্য ফর্ম সঠিক ভুল
"এক্সএমএল এইচটিটিপি অনুরোধ" XmlHttpRequest XMLHTTPRequest
"নতুন গ্রাহক আইডি" newCustomerId newCustomerID
"অভ্যন্তরীণ স্টপওয়াচ" innerStopwatch innerStopWatch
"iOS এ IPv6 সমর্থন করে" supportsIpv6OnIos supportsIPv6OnIOS
"ইউটিউব আমদানিকারক" 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টি স্পেস ইন্ডেন্ট করা হয়।

সারাংশ খণ্ড

প্রতিটি KDoc ব্লক একটি সংক্ষিপ্ত সারাংশ খণ্ড দিয়ে শুরু হয়। এই খণ্ডটি অত্যন্ত গুরুত্বপূর্ণ: এটি পাঠ্যের একমাত্র অংশ যা নির্দিষ্ট প্রসঙ্গে যেমন ক্লাস এবং পদ্ধতি সূচীতে প্রদর্শিত হয়।

এটি একটি খণ্ড – একটি বিশেষ্য বাক্যাংশ বা ক্রিয়াপদ, একটি সম্পূর্ণ বাক্য নয়। এটি " A `Foo` is a... ", বা " This method returns... " দিয়ে শুরু হয় না, বা এটিকে " Save the record. যাইহোক, খণ্ডটি বড় আকারের এবং বিরামচিহ্নিত হয় যেন এটি একটি সম্পূর্ণ বাক্য।

ব্যবহার

সর্বনিম্নভাবে, KDoc প্রতিটি public টাইপের জন্য এবং এই ধরনের প্রতিটি public বা protected সদস্যের জন্য উপস্থিত থাকে, কিছু ব্যতিক্রম নীচে উল্লেখ করা হয়েছে।

ব্যতিক্রম: স্ব-ব্যাখ্যামূলক ফাংশন

KDoc হল ঐচ্ছিক “সহজ, সুস্পষ্ট” ফাংশন যেমন getFoo এবং foo মত বৈশিষ্ট্য, যেখানে সত্যিই এবং সত্যিকার অর্থে “foo ফেরত দেওয়া” ছাড়া আর কিছু বলার মতো কিছু নেই।

প্রাসঙ্গিক তথ্য বাদ দেওয়ার জন্য এই ব্যতিক্রমটি উদ্ধৃত করা উপযুক্ত নয় যা একজন সাধারণ পাঠকের জানার প্রয়োজন হতে পারে। উদাহরণস্বরূপ, getCanonicalName নামের একটি ফাংশন বা canonicalName নামের সম্পত্তির জন্য, এর ডকুমেন্টেশন বাদ দেবেন না (যৌক্তিকতা সহ যে এটি শুধুমাত্র /** Returns the canonical name. */ ) যদি একজন সাধারণ পাঠকের ধারণা নাও থাকতে পারে যে শব্দটি কী "ক্যাননিকাল নাম" মানে!

ব্যতিক্রম: ওভাররাইড

KDoc সর্বদা একটি পদ্ধতিতে উপস্থিত থাকে না যা একটি সুপারটাইপ পদ্ধতিকে অগ্রাহ্য করে।