一预鬓、對變量延遲初始化
應用場景:如果一個類中揪漩,存在很多全局變量實例组民,我們不得不做許多的非空判斷慢味,即使我們非常確定他們不會為空奕短。比如:
class MainActivity : AppCompatActivity() {
private var recyclerAdapter: RecyclerAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
recyclerView.adapter = RecyclerAdapter(list)
...
}
override fun onClick(view:View?) {
...
recyclerAdapter?.notifyDataSetChanged()
...
}
}
使用lateinit關(guān)鍵字奠衔,他會告訴Kotlin編譯器沉御,我會在晚些時候?qū)@個變量進行初始化窃爷,這樣就不用在一開始的時候?qū)⑺x值為null了:
class MainActivity : AppCompatActivity() {
private lateinit var recyclerAdapter: RecyclerAdapte
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
recyclerView.adapter = RecyclerAdapter(list)
...
}
override fun onClick(view:View?) {
...
recyclerAdapter.notifyDataSetChanged()
...
}
}
但是我們一定要注意粤剧,使用lateinit關(guān)鍵字一定要確保它在被調(diào)用前已經(jīng)完成了和初始化工作痘括,否則Kotlin無法保證程序的安全性长窄。
另外滔吠,還可以通過代碼來判斷一個全局變量是否已經(jīng)完成了初始化:
if(!::recyclerAdapter.isInitialized){
recyclerAdapter = RecyclerAdapter(list)
}
一、使用密封類優(yōu)化代碼
看下面這段代碼:
interface Result
class Success(val msg: String) : Result
class Fail(val error: Error) : Result
fun getResult(result: Result) = when (result) {
is Success -> result.msg
is Fail -> result.error.message
else -> throw IllegalArgumentException()
}
我們使用when語句來判斷挠日,每次都必需寫else疮绷,而且如果我們新增了一個繼承Result的類,但在getResult()方法中忘記添加相應的條件了肆资,這時程序就會默認走else方法矗愧,導致崩潰。
密封類的關(guān)鍵字是 sealed class郑原,用法非常簡單:
sealed class Result
class Success(val msg: String) : Result()
class Fail(val error: Error) : Result
可以看到唉韭,只是將interface關(guān)鍵在改成了sealed class.另外密封類是可繼承的類,所以在繼承它時要加上括號犯犁。
改成密封類之后属愤,方法中的else條件就不需要了。
這是因為當在when語句中傳入一個密封類變量作為條件時酸役,Kotlin編譯器會自動檢查該密封類有哪些子類住诸,并強制要求你講每一個子類所對應的的條件全部處理。
另外涣澡,密封類及其所有子類只能定義在同一文件的頂層位置贱呐,不能把嵌套在其他類中,這是被密封類底層的實現(xiàn)機制所限制入桂。