延迟初始化

为了满足kotlin编译器的需求,Kotlin代码中存在大量的判空场景。如下述场景,adapter初始赋值为null,后续在onCreate()周期里赋值,在触发点击事件的时候adapter肯定不为null,但为了满足Kotlin编译器要求,还是要进行?.判断

class mainActivity:AppCompatActivity(),View.OnClickListener{
    private var adapter:MsgAdapter?=null
    override fun onCreate(saveInstanceState:Bundle?){
        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?=null
    override fun onCreate(saveInstanceState:Bundle?){
        adapter=MsgAdapter(msgList)
    }
    override fun onClick(v:View?){
        adapter.notifyItemInserted(msgList.size-1)
    }
}

但如果在adapter变量还没有初始化的时候就用到了,程序会崩溃。所以在使用lateinit关键字的时候一定要保证在使用这个变量之前已经完成了初始化工作。此外我们还可以在代码中判断某一变量是否已完成初始化动作,避免重复对一个变量进行初始化

class mainActivity:AppCompatActivity(),View.OnClickListener{
    private lateinit var adapter:MsgAdapter?=null
    override fun onCreate(saveInstanceState:Bundle?){
        if(!::adaper.isInitialized){
            adapter=MsgAdapter(msgList)
        }
    }
}

密封类

密封的类和接口提供类层次结构的受控继承。 密封类的所有直接子类在编译时都是已知的。模块之外不得出现其他子类,并且 定义密封类的包。同样的逻辑也适用于密封接口及其实现: 一旦编译了具有密封接口的模块,就无法创建新的实现。

sealed class Result
class Success():Result()
class Failure():Result()

fun getMsg(result:Result)=when(result){
    is Success-> "success"
    is Failure-> "error"
}

此时如果在这个时候加个Unknow类并且实现Result接口,那么此时getMsg会报错,需要要新加一个Unknow条件分支才能编译通过

密封类及其所有子类只能定义在同一个文件的顶层位置,不能嵌套在其他类里

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐