Kotlin 中的 lateinit 、lazy、let 、apply 、also 、takeif、takeUnless
文章目錄
前提
Kotlin和Groovy等語言一樣,支援閉包(block),如果函式中最後一個引數為閉包,那麼最後一個參可以不寫在括號中,而寫在括號後面,如果只有一個引數,括號也可以去掉。
viewPager.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { } });
那麼在 Kotlin 中,我們可以得到如下程式碼
view.setOnClickListener ({
print("name")
})
只有一個引數,括號可以去掉
view.setOnClickListener {
print("name")
}
lateinit 、by lazy
在 Kotlin 中 lateinit 和 lazy 是兩種不同的延遲初始化 技術。
-
lateinit 只用於 var,而 lazy 只用於 val
-
lazy 應用於單例模式(if-null-then-init-else-return),而且當且僅當變數被第一次呼叫的時候,委託方法才會執行。
-
lateinit 則用於只能生命週期流程中進行獲取或者初始化的變數,比如 Android 的 onCreate()
-
lateinit 只能修飾非 kotlin 基本型別,在 kotlin 中會以 null 初始化由lateinit 修飾的變數,而基礎型別沒有null 。
-
使用 lateinit 修飾的變數,在使用時不必使用
?
或!!
修飾,但是必須在第一次使用時保證為變數賦初值,不然程式會報出空指標異常。 -
使用 by lazy 修飾的變數:
val name by lazy{
name.....
}
在第一次使用 name 時,會執行閉包中的程式碼對變數 name 進行初始化。
let
以當前這個物件作為閉包的 it 引數,返回值是函式裡面最後一行,或者指定 return 。
var str = listof(3,3,6)
fun main(args: Array<String>){
str.let{
println(it)
println(it)
return
}
}
列印記錄:
[3, 3, 6]
[3, 3, 6]
repeat
重複執行閉包裡面的內容
repeat(3){
println("name")
}
列印資訊如下:
name
name
name
with
Calls the specified function block with the given receiver as its receiver and returns its result.
使用給定接收器作為接收器,呼叫指定的功能塊並返回其結果。
apply
呼叫某物件的 apply 函式,在該函式的範圍內,可以使用該物件的任意函式,並且返回該物件。
ArrayList<Int>().apply {
add(1)
add(2)
add(3)
println(this)
}.let { println(it) }
列印結果:
[1, 2, 3]
[1, 2, 3]
run
run 函式的使用基本和 apply 函式相同,唯一不同的是,run 函式的返回值由最後一行決定,而 apply 函式返回該物件。
ArrayList<Int>().run {
add(1)
add(2)
add(3)
println(this)
get(1)
}.let { println(it.toString() + "3535") }
列印日誌:
23535
also
執行閉包,返回呼叫物件 this。
ArrayList<Int>().run {
add(1)
add(2)
add(3)
println(this)
get(1)
}.also {
println(it)
it + 2
}.let { println(it) }
執行結果
[1,2,3]
2
2
最後一個 2
的得到原因為:also 函式為執行閉包中操作後返回 this,那麼在此處 this 便是在 run 函式中返回的元素 – 2。
takeif
如果 滿足 閉包中的條件返回呼叫物件,否則返回 null 。
4.takeIf {
it > 3
}.let {
println(it)
}
執行結果
4
如果具體程式碼如下:
2.takeIf {
it > 3
}.let {
println(it)
}
則執行結果為
null
takeUnless
如果 不滿足 閉包中的條件返回呼叫物件,否則返回 null 。
與 takeif 中相同的例子,得到的結果正好是相反的。