美文网首页
Kotlin编码规范

Kotlin编码规范

作者: 见字如晤一 | 来源:发表于2022-02-24 09:20 被阅读0次

    该规范参考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)
    }
    

    相关文章

      网友评论

          本文标题:Kotlin编码规范

          本文链接:https://www.haomeiwen.com/subject/movolrtx.html