1、空安全
在 Kotlin 中,类型系统区分一个引用可以容纳 null (可空引用)还是不能容纳(非空引用)。
1.1、String 类型的常规变量不能容纳 null:
如下图a1正常编译运行,a2会报编译错误


如果要允许为空,可以声明a2为可空字符串,写作 String?:
如果你调用 a1的方法或者访问它的属性,它保证不会导致 NPE
但是如果你想访问 a2 的同一个属性,那么这是不安全的,并且编译器会报错,需要采用 ?. 的安全的调用方式

1.2、Elvis操作符 ?:
使用场景:当有一个可空的引用 a 时,可以说“如果 a不是 null,就使用它;否则使用某个非空的值”
Val l = a?.length ?:-1
如果 ?: 左侧表达式不是 null,Elvis 操作符就返回其左侧表达式,否则返回右侧表达式。 请注意,当且仅当左侧为 null 时,才会对右侧表达式求值。

1.3、非空断言运算符 !!
将任何值转换为非空类型,若该值为 null 则抛出异常。可以写 !!

1.4 安全的类型转换
如果对象不是目标类型,那么常规类型转换可能会导致 ClassCastException。 另一个选择是使用安全的类型转换,如果尝试转换不成功则返回 null:

1.5 可空的类型集合
如果你有一个可空类型元素的集合,并且想要过滤非空元素,你可以使用 filterNotNull 来实现:

2、相等性
Kotlin 中有两类相等性:
结构相等( == 用 equals() 检测)
引用相等( === 两个引用指向同一对象)
结构相等由 == 以及其否定形式 != 操作判断。 按照约定,像 a == b 这样的表达式会翻译成:
A?.equals(b) ?: (b === null)
如果 a 不是 null 则调用 equals(Any?) 函数,否则(a 是 null)检测 b 是否与null 引用相等。
引用相等由 === (以及其否定形式 !==)操作判断。a === b 当且仅当 a 与 b 指向同一个对象时求值为 true。对于运行时以原生类型表示的值 (例如 Int), === 相等检测等价于 == 检测。

学习资料
基本语法、习惯用法、编码规范:
https://book.kotlincn.net/text/basic-syntax.html
Android 开发中常见 Kotlin 模式:
https://developer.android.com/kotlin/common-patterns?hl=zh-cn