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
}
選好的名字
[編輯]類別的名字通常會是某個名詞或名詞片語,解釋這個類別在做什麼,比方說:List
,PersonReader
。
函式的名稱通常是動詞或者動詞片語,解釋這個函式的行為,比方說:close
,readPersons
。
函式名稱應該要看得出來其行為是改變輸入的參數,還是回傳一個新的物件。比方說: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)