Kotlin使用技巧(2)-->延遲初始化和密封類

一、對變量延遲初始化

應用場景:如果一個類中,存在很多全局變量實例,我們不得不做許多的非空判斷,即使我們非常確定他們不會爲空。比如:

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關鍵字,他會告訴Kotlin編譯器,我會在晚些時候對這個變量進行初始化,這樣就不用在一開始的時候將它賦值爲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關鍵字一定要確保它在被調用前已經完成了和初始化工作,否則Kotlin無法保證程序的安全性。

另外,還可以通過代碼來判斷一個全局變量是否已經完成了初始化:

if(!::recyclerAdapter.isInitialized){
   recyclerAdapter = RecyclerAdapter(list)
}

一、使用密封類優化代碼

看下面這段代碼:

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方法,導致崩潰。

密封類的關鍵字是 sealed class,用法非常簡單:

sealed class Result
class Success(val msg: String) : Result()
class Fail(val error: Error) : Result

可以看到,只是將interface關鍵在改成了sealed class.另外密封類是可繼承的類,所以在繼承它時要加上括號

改成密封類之後,方法中的else條件就不需要了。
這是因爲當在when語句中傳入一個密封類變量作爲條件時,Kotlin編譯器會自動檢查該密封類有哪些子類,並強制要求你講每一個子類所對應的的條件全部處理。

另外,密封類及其所有子類只能定義在同一文件的頂層位置,不能把嵌套在其他類中,這是被密封類底層的實現機制所限制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章