Files
Obsidian-Main/20.01. Programming/Kotlin/run, let, with, also 和 apply.md

3.6 KiB
Raw Permalink Blame History

run, let, with, alsoapply 這幾個都是可以搭配 object 使用的函數,它們之間的差異不大,主要是讓程式在語意上更加流暢。 以下解釋各個的差別。

歸納

變數名稱 自訂變數名稱 回傳
run() 最後一行
with() this No 最後一行
object.run this No 最後一行
object.let it Yes 最後一行
object.also it Yes this
object.apply this No this

run

run 後面的區塊會回傳「最後一行」,所以可以進行「串接」。如下:

run {
    val telephone = Telephone()
    telephone.whoCallMe = "English"
    telephone    // <--  telephone 被帶到下一個 Chain
}.callMe("Softest part of heart")    // <-- 這裡可以執行 `Telephone` Class 的方法

object.run

object.run#run是一樣的,也是回傳「最後一行」,只是 object.run 是讓 object 呼叫的,而且 lambda scope 中的物件會變成 thisthis 可以省略,但是不可以自訂變數名稱,如下:

val anObject = MyObject()
anObject.run {
    this.doSomething()  // this就是anObjectthis可以省略
}

with

with(T) 之中的傳入值可以以 this (稱作 identifier) 在 scope 中取用,不用打出 this也沒關係。雖然, with 也會將最後一行回傳。但是因為 with 沒有先判斷物件是否為 null,所以 scope 中還是要用?來判斷是否 null,如下:

val anObject = makeMyObject()  // anObject有可能是null
with(anObject) {
    this?.doSomething()  // this就是anObjectthis可能是null
}

object.let

let 的 scope 裡,物件是 it,可以自訂變數名稱,一樣會回傳最後一行。如下:

val anObject = makeMyObject()  
anObject?.let {          // anObject有可能是null所以要先用?判斷
    it.doSomething()     // it就是anObject在scope內一定不是null
}

object.also

also 的 scope 裡,物件是 it,可以自訂變數名稱,但是不是回傳最後一行,是回傳自己(也就是 it)。如下:

val anObject = makeMyObject()  
anObject?.also {       // anObject有可能是null所以要先用?判斷
    it.doSomething()   // it就是anObject在scope內一定不是null
}.also {
    it.doSomething2()  // it就是anObject
}.also {
    it.doSomething3()  // it就是anObject
}

object.apply

apply 的 scope 裡,物件是 this,不可以自訂變數名稱,但是不是回傳最後一行,是回傳自己(也就是 this)。如下:

val anObject = makeMyObject()  
anObject?.also {         // anObject有可能是null所以要先用?判斷
    this.doSomething()   // this就是anObject在scope內一定不是null
}.also {
    this.doSomething2()  // this就是anObject
}.also {
    this.doSomething3()  // this就是anObject
}

參考