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)