Kotlin编码规范

该规范参考Kotlin语言中文站进行定义

应用codeStyle

一、源代码组织结构

1、目录结构

Kotlin和Java相似,都有包的概念。每一个Kotlin文件都能以一条package语句开头,那么这个文件中的所有类、函数及属性都会被放到这个包中,属于这个包。
如果其它文件中也是以同样的package语句开头,那么它们属于同一个包,不管文件放在哪个目录结构下,不用和Java一样,必须把类文件放在和包结构相匹配的目录结构下。同一个包下的内容可以互相使用。
Kotlin推荐的目录结构遵循省略了公共根包的包结构,即每个文件应存储在与其 package 语句对应的目录中。

一句话概况:每个文件应存储在与其 package 语句对应的目录中!

2、源文件名称

如果 Kotlin 文件包含单个类(以及可能相关的顶层声明),那么文件名应该与该类的名称相同,并追加 .kt 扩展名。如果文件包含多个类或只包含顶层声明, 那么选择一个描述该文件所包含内容的名称,并以此命名该文件。 使用首字母大写的驼峰风格, 例如 ProcessDeclarations.kt

一句话概况:文件名采用驼峰命名

3、类布局

通常,一个类的内容按以下顺序排列:

属性声明与初始化块
次构造函数
方法声明
伴生对象

不要按字母顺序或者可见性对方法声明排序,也不要将常规方法与扩展方法分开。而是要把相关的东西放在一起,这样从上到下阅读类的人就能够跟进所发生事情的逻辑。

将嵌套类放在紧挨使用这些类的代码之后。如果打算在外部使用嵌套类,而且类中并没有引用这些类,那么把它们放到末尾,在伴生对象之后。

二、命名规则

在 Kotlin 中,包名与类名的命名规则非常简单:
包的名称总是小写且不使用下划线(org.example.project)。 通常不鼓励使用多个词的名称,但是如果确实需要使用多个词,可以将它们连接在一起或使用驼峰风格(org.example.myProject)。

类与对象的名称以大写字母开头并使用驼峰风格:

open class DeclarationProcessor { /*……*/ }

object EmptyDeclarationProcessor : DeclarationProcessor() { /*……*/ }

函数名

函数、属性与局部变量的名称以小写字母开头、使用驼峰风格而不使用下划线:

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

例外:用于创建类实例的工厂函数可以与抽象返回类型具有相同的名称:

interface Foo { /*……*/ }

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

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

属性名

常量名称(标有 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 })也可使用首字母大写的常规驼峰名称,具体取决于用途。

幕后属性的名称

如果一个类有两个概念上相同的属性,一个是公共 API 的一部分,另一个是实现细节,那么使用下划线作为私有属性名称的前缀(这种方式借鉴了Flutter私有属性的命名方式):

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

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

命名有良好习惯

类的名称通常是用来解释类是什么的名词或者名词短语:xxxListAdapter、 PersonReader。

方法的名称通常是动词或动词短语,说明该方法做什么:close、 readPersons。 修改对象或者返回一个新对象的名称也应遵循建议。例如 sort 是对一个集合就地排序,而 sorted 是返回一个排序后的集合副本。

名称应该表明实体的目的是什么,所以最好避免在名称中使用无意义的单词 。

当使用首字母缩写作为名称的一部分时,如果缩写由两个字母组成,就将其大写(IOStream); 而如果缩写更长一些,就只大写其首字母(XmlFormatter、 HttpInputStream)。

格式化

使用 4 个空格缩进。不要使用 tab。(可在AS中设置好code style,一个tab等于4个空格进行缩进)


image.png

对于花括号,将左花括号放在结构起始处的行尾,而将右花括号放在与左括结构横向对齐的单独一行。

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

在 Kotlin 中,分号是可选的,因此换行很重要。语言设计采用 Java 风格的花括号格式,如果尝试使用不同的格式化风格,那么可能会遇到意外的行为。

横向空白

在二元操作符左右留空格(a + b)。例外:不要在“range to”操作符(0..i)左右留空格。

不要在一元运算符左右留空格(a++)

在控制流关键字(if、 when、 for 以及 while)与相应的左括号之间留空格。
(这里容易被忽略,小组讨论是否需要。建议使用)

不要在主构造函数声明、方法声明或者方法调用的左括号之前留空格。

class A(val x: Int)

fun foo(x: Int) { …… }

fun bar() {
    foo(1)
}

绝不在 (、 [ 之后或者 ]、 ) 之前留空格。

绝不在. 或者 ?. 左右留空格:foo.bar().filter { it > 2 }.joinToString(), foo?.bar()

在 // 之后留一个空格:

// 这是一条注释

不要在用于指定类型参数的尖括号前后留空格:class Map<K, V> { …… }

不要在 :: 前后留空格:Foo::class、 String::length

不要在用于标记可空类型的 ? 前留空格:String?

冒号

在以下场景中的冒号":"之前留一个空格:

当它用于分隔类型与超类型时;
当委托给一个超类的构造函数或者同一类的另一个构造函数时;
在 object 关键字之后。
而当分隔声明与其类型时,不要在 : 之前留空格。(指声明属性时或者函数定义返回类型时)

在 : 之后总要留一个空格。

abstract class Foo<out T : Any> : IFoo {
    abstract fun foo(a: Int): T
}

class FooImpl : Foo() {
    constructor(x: String) : this(x) { /*……*/ }
    
    val x = object : IFoo { /*……*/ } 
}

类头格式化

有少数几个参数的类可以写成一行:

class Person(id: Int, name: String)

具有较长类头的类应该格式化,以使每个主构造函数参数位于带有缩进的单独一行中。 此外,右括号应该另起一行。如果我们使用继承,那么超类构造函数调用或者实现接口列表应位于与括号相同的行上:

class Person(
    id: Int, 
    name: String,
    surname: String
) : Human(id, name) {
    // ……
}

对于多个接口,应首先放置超类构造函数调用,然后每个接口应位于不同的行中:

class Person(
    id: Int, 
    name: String,
    surname: String
) : Human(id, name),
    KotlinMaker {
    // ……
}

对于具有很长超类型列表的类,在冒号后面换行,并横向对齐所有超类型名:

class MyFavouriteVeryLongClassHolder :
    MyLongHolder<MyFavouriteVeryLongClass>(),
    SomeOtherInterface,
    AndAnotherOne {

    fun foo() { /*...*/ }
}

为了将类头与类体分隔清楚,当类头很长时,可以在类头后放一空行 (如上例所示)或者将左花括号放在独立行上:

class MyFavouriteVeryLongClassHolder :
    MyLongHolder<MyFavouriteVeryLongClass>(),
    SomeOtherInterface,
    AndAnotherOne 
{
    fun foo() { /*...*/ }
}

个人较倾向于第一种:花括号放在超类后

构造函数参数使用常规缩进(4 个空格)。

理由:这确保了在主构造函数中声明的属性与 在类体中声明的属性具有相同的缩进。

Unit

如果函数返回 Unit 类型,该返回类型应该省略:

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

}

Lambda表达式

在lambda表达式中, 大括号左右要加空格,分隔参数与代码体的箭头左右也要加空格 。lambda表达应尽可能不要写在圆括号中

list.filter { it > 10 }.map { element -> element * 2 }

在非嵌套的短lambda表达式中,最好使用约定俗成的默认参数 it 来替代显式声明参数名 。在嵌套的有参数的lambda表达式中,参数应该总是显式声明。

在多行的 lambda 表达式中声明参数名时,将参数名放在第一行,后跟箭头与换行符:

appendCommaSeparated(properties) { prop ->
    val propertyValue = prop.get(obj)  // ……
}

如果参数列表太长而无法放在一行上,请将箭头放在单独一行:

foo {
   context: Context,
   environment: Env
   ->
   context.configureEnv(environment)
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容