Effective Kotlin中文版
  • ReadMe
  • 前言
  • 第一部分:良好的代码
    • 第一章:安全性
      • 第1条:限制可变性
      • 第2条:最小化变量的作用域
      • 第3条:尽可能消除平台类型
      • 第4条: 不要暴露需要推断的类型
      • 第5条:指明你期望的参数和状态
      • 第 6 条: 优先使用标准错误,而不是自定错误
      • 第7条:当返回结果可能缺失时,优先使 null 或 Failure
      • 第8条:妥善处理空值
      • 第9条: 使用 use 来关闭资源
      • 第10条:编写单元测试
    • 第二章:可读性
      • 第11条:为了可读性设计代码
      • 第12条:操作符的行为应该与其名称一致
      • 第13条:避免返回或操作 Unit?
      • 第14条: 在变量不清晰时指定其类型
      • 第15条:考虑显式引用接收者
      • 第16:属性应该代表状态,而非行为
      • 第17条:考虑使用具名参数
      • 第18条:遵守编程惯例
  • 第二部分:良好的设计
    • 第三章:可重用性
      • 第19条:不要重复知识
      • 第20条:不要重复实现常用算法
      • 第21条 使用属性代理来提取公共的属性模式
      • 第22条:当实现公共算法时使用泛型
      • 第23条:避免隐藏类型参数
      • 第24条:在使用泛型时考虑型变
      • 第25条:在不同的平台上提取公共模块进行重用
    • 第四章:抽象设计
      • 第26条:每个方法都应该基于单一的抽象级别而编写
      • 第27条:使用抽象来保护代码不受更改
      • 第28条:指定 Api 的稳定性
      • 第29条:考虑包装扩展 API
      • 第30条:最小化元素的可见性
      • 第31条:用文档定义合约
      • 第32条:遵守抽象合约
    • 第五章:对象的创建
      • 第33条:考虑使用工厂方法代替构造函数
      • 第34条:考虑带命名默认参数的主构造函数
      • 第35条:考虑为复杂的对象创建定义 DSL
    • 第六章:类的设计
      • 第36条:组合优于继承
      • 第37条:使用数据修饰符来表示一组数据
      • 第38条:使用函数类型而不是接口来传递操作和行为
      • 第39条:类层次结构优于标签类
      • 第40条:遵守 equals 的合约
      • 第41条:遵守 hashCode 的合约
      • 第42条:遵守 compareTo 的合约
      • 第43条: 考虑将 API 的非必要部分提取到扩展函数中
      • 第44条:避免在成员中定义扩展
  • 第三部分:性能
    • 第七章:让开发成本更低
      • 第45条:避免不必要的对象创建
      • 第46条:给高阶函数使用 inline 修饰符
      • 第47条:考虑使用内联类
      • 第48条:消除过时的对象引用
    • 第八章:高效的集合处理
      • 第49条:在具有多个处理步骤的大型集合上,优先使用 Sequence
      • 第50条:限制操作步骤的数量
      • 第51条:性能关键处考虑使用原语的数组
      • 第52条:考虑使用可变集合
Powered by GitBook
On this page
  1. 第一部分:良好的代码
  2. 第二章:可读性

第18条:遵守编程惯例

Basis

Kotlin 已经建立了良好的代码约定,在文档中被称为 “编程惯例(Coding Conventions)”,这些惯例并非对所有项目都是最好的,但对我们来说,作为一个社区,在所有项目中都遵守这些惯例是最理想的。多亏这些惯例,能使得我们:

  • 在不同项目之间切换更加容易

  • 代码更具可读性,甚至对外部开发人员也是如此

  • 更容易理解代码的工作原理

  • 将代码 merge 到公共仓库,或将部分代码从一个项目迁移到另一个项目更容易

程序员应该熟悉文档中描述的那些约定,当它们发生变化时 —— 随着时间的推移可能会在某种程度上发生变化 —— 它们也应该被遵守。因为这很难做到,所以有两种工具能帮助你

  • IntelliJ formatter 可以根据官方的编程风格设置代码自动格式化,为此,跳转到 Setting | Editor | Code Style | Kotlin, 点击右上角 "Setting from...",并从菜单中选择 “Predefined style / Kotlin style guide”

  • klint —— 主流的检查程序,它可以分析的你代码,并指出你所有违反编码惯例的地方

看看 Kotlin 项目,我发现它们很多都符合大部分的编程惯例,这可能是因为 Kotlin 主要遵循着 Java 编码惯例,而今天大多数 Kotlin 开发人员都是曾经的 Java 开发人员。我发现一个经常被违背的惯例是去如何格式化类和函数,按照惯例,具有短主构造函数的类可以在一行中定义:

class FullName(val name: String, val surname: String)

然而,有很多参数的类应该被格式化,使每个参数都放在其他行,并且第一行没有参数:

class Person(
    val id: Int = 0,
    val name: String = "",
    val surname: String = ""
) : Human(id, name) {
    // body
}

类似地,这是我们格式化长函数的方式:

public fun <T> Iterable<T>.joinToString(
    separator: CharSequence = ", ",
    prefix: CharSequence = "",
    postfix: CharSequence = "",
    limit: Int = -1,
    truncated: CharSequence = "...",
    transform: ((T) -> CharSequence)? = null
): String {
    // ...
}

请注意,上面这两个例子,都把第一个参数放在了第一行,然后其它参数的缩进与其相同, 这可能和其它语言上参数的惯例不同。

// 不要这么做!
class Person(val id: Int = 0,
             val name: String = "",
             val surname: String = "") : Human(id, name){
                 // body
}

上面这段代码有两个问题:

  1. 每个类的参数都会根据其类名的长度,以不同的缩进开始。另外,当我们更改类名时,我们需要调整所有主构造函数参数的缩进

  2. 以这种方式定义的类往往会太宽,宽度是 class关键字 + 类名 + 最长构造函数的参数, 可能还要加上其超类和接口

一些团队可能决定使用些许不同的惯例,这很好,但这些约定应该在给定的项目中被遵守使用。每个项目应该看起来像是同一个人写的,而不是一群人相互争斗而写的。开发人员通常对编码惯例不够重视,但是它们在实战中很重要,在最佳实战的书中,一定需要至少一个小的章节来专门介绍可读性的重要性。阅读它们,使用静态代码扫描器来帮助你遵守这些惯例,将它们运用到你的项目中,通过遵守编码约定,使 Kotlin 项目对我们所有人来说都是更好的。

Previous第17条:考虑使用具名参数Next第三章:可重用性

Last updated 2 years ago