Kotlin学习之延迟初始化和密封类

1、延迟初始化

对于一些变量,如果我们要在后面才对它进行复制,那么我们就要在前面给他初始化为空

class MainActivity : AppCompatActivity(), View.OnClickListener{

    private var adapter: MsgAdapter? =null
	
    override fun onCreate(savedInstanceState: Bundle?) {//判断是否被初始化
        if(!::adapter.isInitialized) {
            adapter = MsgAdapter(msgList)
        }}

并且在使用使还要进行判空操作

override fun onClick(v: View?) {
    …
    adapter?.notifyItemInserted(msgList.size - 1)}

延迟初始化使用的是lateinit关键字,它可以告诉Kotlin编译器,我会在晚些时候对这个变量进行初始化,这样就不用在一开始的时候将它赋值为null了,在后面也可以直接调用。

class MainActivity : AppCompatActivity(), View.OnClickListener {

    private lateinit var adapter: MsgAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        …
        adapter = MsgAdapter(msgList)}

    override fun onClick(v: View?) {
        …
        adapter.notifyItemInserted(msgList.size - 1)}

}

同时我们还可以用下面操作判断是否初始化

if(!::adapter.isInitialized) {
	adapter = MsgAdapter(msgList)
}

2、密封类

首先我们定义一个Result接口,用Success和Failure实现Result,用于处理成功的结果和失败的结果

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

接下来再定义getResultMsg()方法接受一个Result参数,我们通过when语句来判断:如果Result属于Success,就返回成功的消息,如果Result属于Failure,就返回失败的消息

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

到目前为止,代码都是没有问题的,但比较讨厌的是,接下来我们不得不再编写一个else条件,否则Kotlin编译器会认为这里缺少条件分支,代码将无法通过编译。

另外,编写else条件还有一个潜在的危险。如果我们新增一个UnKnow类并实现Result接口,用于表示未知的处理结果,但忘记再getResultMsg()方法中添加相应的条件分支,这个时候编译器是不会提醒我们的,而是会在运行的时候进入else分支,从而判处异常导致程序崩溃。

而使用密封类优化代码,就可以保证Kotlin编译器会自动检查该密封类有哪些子类,并强制要求你将每一个子类所对应的条件全部处理,且即使没有编写else条件,也不可能会出现漏写条件分支的情况。

//定义密封类
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 -> "Error is ${result.error.message}"
}

你可能感兴趣的:(笔记,kotlin,android,kotlin)