美文网首页
Kotlin开发规范

Kotlin开发规范

作者: 浩林Leon | 来源:发表于2020-02-26 16:31 被阅读0次

    一、 命名格式

    总体来说,Kotlin命名格式要和Java命名规范保持一致,因为Kotlin也是JVM兼容的语言。

    包名

    包的命名规则和Java一样:全小写,当遇到多个词连接的场景,不要使用下划线(_)和连字号(-)。

    推荐
    package vn.asiantech.android
    
    
    不推荐
    package Vn.Asiantech.Android
    
    

    类和接口

    命名遵守大驼峰规则(首字母大写)。

    推荐
    HomeActivity
    MainFragment
    
    

    方法

    命名遵守小驼峰规则(首字母小写)。

    推荐
    setData
    getApiNews
    
    

    字段(Fields)

    总体来说,字段命名遵守小驼峰规则,不建议使用匈牙利法

    推荐
    class MyClass {
      var publicField: Int = 0
      val person = Person()
      private var privateField: Int?
    }
    
    

    而伴生对象中的常量定义要遵守规则:全大写,单词连接使用下划线。

    companion object {
      const val THE_ANSWER = 42
    }
    
    

    二、变量和参数

    一句话概括: 小驼峰命名法。
    不建议使用单个字符的变量,除非是循环中的临时变量。

    其他

    首字母缩略词作为完整单词看待,适时选择命名规则。

    推荐
    XMLHTTPRequest
    URL: String? 
    findPostByID
    
    
    不推荐
    XmlHttpRequest
    url: String
    findPostById
    
    

    三、间距

    缩进

    缩进使用4个空格,不建议使用tabs - 制表符。

    闭包

    闭包的缩进使用2个空格,

    推荐
    for (i in 0..9) {
      Log.i(TAG, "index=" + i)
    }
    
    
    不推荐
    for (i in 0..9) {
        Log.i(TAG, "index=" + i);
    }
    
    

    自动换行

    新的换行缩进使用4个空格,而不是默认的8个。

    推荐
    val widget: CoolUiWidget =
        someIncrediblyLongExpression(that, reallyWouldNotFit, on, aSingle, line)
    
    
    不推荐
    val widget: CoolUiWidget =
            someIncrediblyLongExpression(that, reallyWouldNotFit, on, aSingle, line)
    
    

    换行

    • 每行不应超过130个字符,这在Android Studio内可以配置。
    • 如果单行代码超过限制需要换行显示,使用, / : / { , = 作为首行的结尾。
    推荐
    fun setData(name: String, age: Int, class: String, date: String, message: String,
         time: String) {
    }
    
    fun getInfo(name: String, birth: String, age: Int, weight: Float, hight: Float) =
       getInfo().apply {
       }
    
    data class Animal(private val weight: Float, private val hight: Float) :
             AbstractAnimal() {
    }
    
    

    垂直间距

    方法体之间保留一个空行,这样可以让结构清晰。
    方法体内的空行用来分割不同功能,这样如果一个方法内分多个部分,也许需要重构代码了。

    冒号 (:)

    • 类型和父类型之间的冒号前面要保留空格,而变量和类型之间的冒号前没有空格。
    推荐
    interface Foo<out T : Any> : Bar {
        fun foo(a: Int): T
    }
    
    // 申明变量类型
    
    val firstName: String
    
    
    不推荐
    interface Foo<out T:Any>: Bar {
        fun foo(a : Int):T
    }
    
    // 申明变量类型
    
    val firstName:String
    
    
    • 在定义类的时候,在结构体的右括号和类主题的左括号之间保留空格,结构体的每个参数单行显示。
    推荐
    class User(
        public open var firstName: String,
        public open var lastName: String
    ) {}
    
    
    不推荐
    class User(public open var firstName: String, public open var lastName: String){}
    
    
    • 在定义子类或实现接口的时候,上面提到的规则仍然适用,且冒号和父类名之间要保留空格,冒号和结构体之间不需要空格。
    推荐
    class User(
        public open var firstName: String,
        public open var lastName: String
    ): RealmObject() {}
    
    

    分号(;)

    在Kotlin中避免使用分号。

    推荐
    val horseGiftedByTrojans = true
    if (horseGiftedByTrojans) {
      bringHorseIntoWalledCity()
    }
    
    
    不推荐
    val horseGiftedByTrojans = true;
    if (horseGiftedByTrojans) {
      bringHorseIntoWalledCity();
    }
    
    

    括号格式 {}

    • 方法体的大括号和其他大括号首括号和前面代码在同一行,尾括号新起一行。
    推荐
    class MyClass {
      fun doSomething() {
        if (someTest) {
          // ...
        } else {
          // ...
        }
      }
    }
    
    
    不推荐
    class MyClass
    {
      fun doSomething()
      {
        if (someTest)
        {
          // ...
        }
        else
        {
          // ...
        }
      }
    }
    
    

    if 条件 括号格式

    • 条件判断语句必须内嵌在括号里,无论其是多少行。
    推荐
    if (someTest) {
      doSomething()
    }
    if (someTest) { doSomethingElse() }
    
    
    不推荐
    if (someTest)
      doSomething()
    if (someTest) doSomethingElse()
    
    

    四、类型

    尽可能使用Kotlin原生类型。

    Unit

    避免显式地声明Unit类型,因为不显式声明返回类型的函数都会返回 Unit 类型。

    推荐
    fun doSomething()
    
    
    不推荐
    fun doSomething(): Unit
    
    

    类型推导

    优先使用类型推导

    推荐
    val something = MyType()
    val meaningOfLife = 42
    
    
    不推荐
    val something: MyType = MyType()
    val meaningOfLife: Int = 42
    
    

    常量 vs 变量

    定义常量时使用关键词val, 定义变量时使用关键词var
    建议: 把所有的值使用val定义,且只在编译器警告的时候修订为var

    伴生对象

    伴生对象应定义在类文件的上面,而关于伴生对象的命名规范要遵守Java标准规范。表示常量 需加 const

    推荐
    class MainFragment: Fragment() {
        companion object {
            const val TYPE_VIEW_HEADER = 0
            const val TYPE_VIEW_FOOTER = 1
        }
    }
    
    
    不推荐
    class MainFragment: Fragment() {
        companion object {
            val TypeViewHeader = 0
            val TypeViewFooter = 1
        }
    }
    
    

    字符串

    推荐使用字符串插值语法糖 ${}

    推荐
    val fullName = "${user.firstName} ${user.lastName}"
    
    
    不推荐
    val fullName = user.firstName + " " + user.lastName
    
    

    选配型(?)

    变量和方法返回可以声明为选配型,这种情况赋值null也是允许的。

    使用隐式拆包!!时候要小心,只能在确认实例对象在被使用前已经初始化,如在Activity方法onCreate使用的子视图。

    在为选配型变量和参数命名的时候,不用使用类maybeViewoptionalString的名称,因为选配类型已经表明了这一点。

    在访问选配型变量值时,可使用可选链(Optional Chaining)。

    editText?.setText("foo")
    
    

    五、习惯

    使用IDE提示

    val array = ArrayList<Int>()
    array[0]
    
    // or
    
    activity().finish()
    
    
    不推荐
    val array = ArrayList<Int>()
    array.get(0)
    
    // or
    
    getActivity().finish()
    
    

    it 在 Lambda 语句中适应较广范围。

    推荐
    { 
      it?.let { animal -> animal.foo() }
    }
    
    
    不推荐
    { animal -> 
      animal?.let { it.foo() }
    }
    
    

    使用类型推断,除非是难以理解的时候。

    推荐
    //属性
    val age = 0       // Int
    val foo = 10L     // Long
    val height = 100f // Float
    
    //函数
    // return Boolean
    fun Context.isConnectToWifi() =
          (getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager)
             .activeNetworkInfo?.type == ConnectivityManager.TYPE_WIFI
    
    // return Point
    fun Display.getSize(): Point = Point().apply { getSize(this) }
    
    

    不要显式地写for循环。

    Kotlin中集合的支持forEach遍历。

    推荐
    (0..9).forEach {
    // todo somethings
    }
    
    (0..9).forEachIndexed { index, value ->
    // todo somethings
    }
    
    
    不推荐
    for (i in 0..9) {
      // todo somethings
    }
    
    

    使用 to 快速创建Pair类的实例。

    推荐
    val pair = Pair(foo, bar) 
    
    
    不推荐
    val pair = foo to bar
    
    

    使用优雅的类型转换。

    推荐
    dog as? Animal ?: throw IllegalArgumentException("not Animal!")
    dog.foo()
    
    
    不推荐
    if (dog !is Animal) {
        throw IllegalArgumentException("not Animal!")
    }
    dog.foo()
    
    

    Getters & Setters

    Kotlin中推荐直接访问属性。

    推荐
    // syntax
    var <propertyName>[: <PropertyType>] [= <property_initializer>]
        [<getter>]
        [<setter>]
    
    // 自定义setter
    var stringRepresentation: String
        get() = this.toString()
        set(value) {
            setDataFromString(value) // parses the string and assigns values to other properties
        }
    
    

    在自定义Getters & Setters时,要遵守Kotlin官方规范

    When语句

    Kotlin的When语句和Java中的Switch有稍许区别,如不会fall through。如果不同的case具有相同的处理策略,使用逗号(,),并且else语句是必须的。

    推荐
    when (anInput) {
      1, 2 -> doSomethingForCaseOneOrTwo()
      3 -> doSomethingForCaseThree()
      else -> println("No case satisfied")
    }
    
    
    不推荐
    when (anInput) {
      1 -> doSomethingForCaseOne()
      2 -> doSomethingForCaseOneOrTwo()
      3 -> doSomethingForCaseThree()
    }
    
    

    变量可视性修饰符

    默认修饰符是public,如果没有其他需要可以省略。

    推荐
    val wideOpenProperty = 1
    private val myOwnPrivateProperty = "private"
    
    
    不推荐
    public val wideOpenProperty = 1
    private val myOwnPrivateProperty = "private"
    
    

    访问控制修饰符

    对于每个类,方法和成员变量,访问控制修饰符要显示定义清晰。

    变量和字段

    单行一个声明。

    推荐
    username: String
    twitterHandle: String
    
    

    普遍来说,每一个文件定义一个类,对于适合的场合依然可以使用内部类。

    Data 类型对象

    对于简单的数据结构,推荐使用data类。

    推荐
    data class Person(val name: String)
    
    
    不推荐
    class Person(val name: String) {
      override fun toString() : String {
        return "Person(name=$name)"
      }
    }
    
    

    枚举

    优先使用静态变量,避免使用枚举类,因为内存开销太大
    如果枚举类没有其他方法,不用换行。

    推荐
    private enum CompassDirection { EAST, NORTH, WEST, SOUTH }
    
    

    六、注解(Annotations)

    使用Java式标准注解,特别是override, 关键字要和函数的声明保持同一行。

    推荐
    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState);
    }
    
    
    不推荐
    fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState);
    }
    
    

    Annotations应该在类的上面, 内联如果注解类中的字段,

    推荐
    @Root(strict=false) 
    public open class User (
        @field:Element public open var firstName: String? = "",
        @field:Element public open var lastName: String? = "",
    ) {...}
    
    
    不推荐
    @Root(strict=false) public open class User (
        @field:Element 
        public open var firstName: String? = "",
        @field:Element 
        public open var lastName: String? = "",
    ) {...}
    
    

    七、XML

    XML文件命名

    文件名要以展示视图的类型作为前缀。

    推荐
    activity_login.xml
    fragment_main_screen.xml
    button_rounded_edges.xml
    
    
    不推荐
    login.xml
    main_screen.xml
    rounded_edges_button.xml
    
    

    缩进

    和Java一样, XML文件使用2个字符缩进。

    使用上下文相关的XML

    任何时候,XML都要定义在相关的文件内。

    Strings => res/values/strings.xml
    Styles => res/values/styles.xml
    Colors => res/color/colors.xml
    Animations => res/anim/
    Drawable => res/drawable
    

    相关文章

      网友评论

          本文标题:Kotlin开发规范

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