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)