Kotlin 延迟初始化和密封类

对变量延迟初始化

延迟初始化使用 lateinit 关键字,它可以告诉编译器会在晚些对这个变量进行初始化,这样就不用在一开始的时候将它赋值为 null 了。如果在变量还没有初始化的情况下直接使用,程序会崩溃,所以当对一个全局变量使用了 lateinit 关键字时,要确保它在任何地方调用之前已经完成了初始化工作。

使用::variable.isInitialized 判断变量是否已经初始化。

使用密封类优化代码

例子:

interface Result
class Success(val msg: String) : Result
class Failure(val error: Exception) : Result

fun getResultMsg(result: Result) = when (result) {
is Success -> result.msg
is Failure -> result.error.message
else -> throw IllegalArgumentException()
}

以上代码中,必须编写 else 条件。如果新增一个 Unknow 类并实现 Result 接口而忘记在 getResultMsg() 方法中添加相应条件分支,编译器不会提醒,而是在运行的时候进入 else 条件,从而抛出异常并导致程序崩溃。密封类很好的解决了这个问题。

密封类的关键字是 sealed class

sealed class Result
class Success(val msg: String) : Result()
class Failure(val error: Exception) : Result()

fun getResultMsg(result: Result) = when (result) {
is Success -> result.msg
is Failure -> result.error.message
}

当在 when 语句中传入一个密封类变量作为条件时,Kotlin 编译器会自动检查该密封类有哪些子类,并强制要求将每一个子类所对应的条件全部处理。密封类及其所有子类只能定义在同一个文件的顶层位置,不能嵌套在其他类中。

参考