Kotlin/程式撰寫慣例

程式撰寫慣例 编辑

套用規範建議 编辑

To configure the IntelliJ formatter according to this style guide, please install Kotlin plugin version 1.2.20 or newer, go to Settings | Editor | Code Style | Kotlin, click Set from… link in the upper right corner, and select Predefined style | Kotlin style guide from the menu.

To verify that your code is formatted according to the style guide, go to the inspection settings and enable the Kotlin | Style issues | File is not formatted according to project settings inspection. Additional inspections that verify other issues described in the style guide (such as naming conventions) are enabled by default.

程式碼架構 编辑

命名規則 编辑

函式名稱 编辑

函式名稱,參數以及本地變數的命名,都是小寫開頭的駝峰格式,不包含底線:

fun processDeclarations() { /*...*/ }
var declarationCount = 1

例外情況:建立某介面的物件所使用的工廠方法,可以直接用該介面命名,因此是大寫開頭:

interface Foo { /*...*/ }

class FooImpl : Foo { /*...*/ }

fun Foo(): Foo { return FooImpl() }

測試函式名稱 编辑

如果是在測試程式碼裡面(也僅有在測試程式程式碼內允許),可以使用重音符「`」括弧起來,內含空白的一段文字作為函式名稱。這類函式目前在 Android 實際環境運作是不支援的。

測試程式碼內,也允許在函式命名裡面使用底線。

class MyTestCase {
     @Test fun `ensure everything works`() { /*...*/ }
     
     @Test fun ensureEverythingWorks_onAndroid() { /*...*/ }
}

屬性名稱 编辑

常量名稱(標有 const 的屬性,或者保存不可變數據的沒有自定義 get 函數的頂層/對象 val 屬性)應該使用大寫、以底線分隔的風格命名:

const val MAX_COUNT = 8
val USER_NAME_FIELD = "UserName"

帶有行為的物件,或者可變數據的頂層/對象屬性的名稱,應該使用小駝峰風格命名:

val mutableCollection: MutableSet<String> = HashSet()

保存單例對象引用的屬性的名稱,可以使用與 object 定義相同的風格命名:

val PersonComparator: Comparator<Person> = /*...*/

對於枚舉常數的命名,可以使用大寫以底線分隔的名稱 (enum class Color { RED, GREEN })也可使用大駝峰命名,具體命名風格取決於用途。

為備存用屬性命名 编辑

如果一個類別有兩個概念相同的屬性,一個是對外的部分,另一個是內部實作細節,那麽使用下劃線作為私有屬性名稱的前綴:

class C {
    private val _elementList = mutableListOf<Element>()

    val elementList: List<Element>
         get() = _elementList
}

選好的名字 编辑

類別的名字通常會是某個名詞或名詞片語,解釋這個類別在做什麼,比方說:ListPersonReader

函式的名稱通常是動詞或者動詞片語,解釋這個函式的行為,比方說:closereadPersons

函式名稱應該要看得出來其行為是改變輸入的參數,還是回傳一個新的物件。比方說:sort 通常是將輸入的集合進行排序,不會回傳新的集合;sorted 則是回傳一個以排序好的集合,不會更動輸入的集合。

命名要能夠看得出用意,所以命名內盡量避免意義不清晰的單字(比方說 Manager,Wrapper 之類)

如果在宣告名稱中使用縮寫,該縮寫只有兩個字母(比方說 I/O)的話,兩個字母都要大寫(IOStream)。如果該縮寫多於兩個字母,那麼只有第一個字母要大寫(XmlFormatter,HttpInputStream)

格式 编辑

用四個空白縮排,不要用 Tab

左大括號前面加上一個空白,並且放在結構一開始這行的最尾端。

右大括號則是獨立一行,並對其結構宣告的開頭。

if (elements != null) {
    for (element in elements) {
        // ...
    }
}

(註記:Kotlin 裡,分號是非必須的,所以換行非常重要。編譯器會假設你是用以上風格的括號方式,如果使用不同風格,可能會導致意外的編譯結果)

橫向空白 编辑

除了「範圍」運算子不需要之外(0..1),二元運算子前後各需要一個空白(比方說: a + b)。

一元運算子前後不可加上空白(比方說:a++)

控制流關鍵字(if、when、for 和 while)和對應的小括號之間要加上一個空白

Do not put a space before an opening parenthesis in a primary constructor declaration, method declaration or method call.

class A(val x: Int)

fun foo(x: Int) { ... }

fun bar() {
    foo(1)
}


Never put a space after (, [, or before ], ).

Never put a space around . or ?.: foo.bar().filter { it > 2 }.joinToString(), foo?.bar()

單行註解的 // 後面要加上一個空白,比方說:// 這是單行註解

Do not put spaces around angle brackets used to specify type parameters: class Map<K, V> { ... }

Do not put spaces around ::: Foo::class, String::length

Do not put a space before ? used to mark a nullable type: String?

As a general rule, avoid horizontal alignment of any kind. Renaming an identifier to a name with a different length should not affect the formatting of either the declaration or any of the usages.

冒號 编辑

類別宣告格式 编辑

修飾宣告 编辑

標註格式 编辑

檔案標註 编辑

函式格式 编辑

Expression body formatting 编辑

Property formatting 编辑

Formatting control flow statements 编辑

Method call formatting 编辑

Chained call wrapping 编辑

Lambda 格式 编辑

文件註解 编辑

避免多餘結構 编辑

Unit 编辑

如果函式回傳 Unit 那麼可以省略

fun foo() { // ": Unit" 被省略了

}

分號 编辑

盡量避免分號

字串樣板 编辑

如果樣板內只有單純變數名稱,避免用大括號包起來。只有在樣板包含比較長的表達式時才需要用大括號處理

println("$name has ${children.size} children")

慣用語言功能 编辑

Immutability 编辑

Default parameter values 编辑

Type aliases 编辑

Lambda parameters 编辑

Returns in a lambda 编辑

Named arguments 编辑

Using conditional statements 编辑

if versus when 编辑

Using nullable Boolean values in conditions 编辑

Using loops 编辑

Loops on ranges 编辑

Using strings 编辑

Functions vs Properties 编辑

Using extension functions 编辑

Using infix functions 编辑

Factory functions 编辑

Platform types 编辑

Using scope functions 编辑

library 的撰寫慣例 编辑

When writing libraries, it's recommended to follow an additional set of rules to ensure API stability:

  • Always explicitly specify member visibility (to avoid accidentally exposing declarations as public API)
  • Always explicitly specify function return types and property types (to avoid accidentally changing the return type when the implementation changes)
  • Provide KDoc comments for all public members, with the exception of overrides that do not require any new documentation (to support generating documentation for the library)

參考資料 编辑