跳到主內容

【Kotlin】run , let, apply, also, let

https://developer.android.com/codelabs/java-to-kotlin#0

https://kotlinlang.org/docs/scope-functions.html

功能

物件引用

傳回值

是擴充函數

let

it

Lambda result

Yes

run

this

Lambda result

Yes

run

-

Lambda result

否:在沒有上下文物件的情況下調用

with

this

Lambda result

否:將上下文物件作為參數。

apply

this

Context object

Yes

also

it

Context object

Yes

下面的專門部分提供了有關這些功能的詳細資訊。
以下是根據預期目的選擇作用域函數的簡短指南:

  • 對不可為 null 的物件執行 lambda:let
  • 在局部範圍內引入表達式作為變數:let
  • 物件配置:apply
  • 物件配置和計算結果:run
  • 在需要表達式的地方運行語句:非擴展run
  • 附加效果:also
  • 將物件的函數呼叫進行分組:with

差異
由於作用域函數本質上很相似,因此了解它們之間的差異非常重要。每個作用域函數之間有兩個主要差異:
  • 他們引用上下文物件的方式。
  • 他們的返回值。
fun main() {
    val str = "Hello"
    // this
    str.run {
        println("The string's length: $length")
        //println("The string's length: ${this.length}") // does the same
    }

    // it
    str.let {
        println("The string's length is ${it.length}")
    }
}
this
run、with、 並透過關鍵字apply引用上下文物件作為 lambda接收器this。因此,在它們的 lambda 中,物件就像在普通類別函數中一樣可用。

大多數情況下,您可以this在存取接收者物件的成員時省略,從而使程式碼更短。另一方面,如果this省略,則很難區分接收者成員和外部物件或函數。
因此this,對於主要透過呼叫其函數或為屬性賦值來操作物件成員的 lambda,建議將上下文物件作為接收者 ()。
val adam = Person("Adam").apply { 
    age = 20                       // same as this.age = 20
    city = "London"
}
println(adam)
it
反過來,let並also引用上下文物件作為 lambda參數。如果未指定參數名稱,則透過隱式預設名稱存取該物件it。it比 更短this,且 的表達式it通常更容易閱讀。

但是,當呼叫物件的函數或屬性時,您不會像this.因此,it當物件主要用作函數呼叫中的參數時,透過存取上下文物件會更好。it如果在程式碼區塊中使用多個變數也更好。
fun getRandomInt(): Int {
    return Random.nextInt(100).also { value ->
        writeToLog("getRandomInt() generated value $value")
    }
}

val i = getRandomInt()
println(i)
下面的範例示範如何將上下文物件引用為帶有參數名稱的 lambda 參數:value。
傳回值
作用域函數因其傳回的結果而有所不同:
fun getRandomInt(): Int {
    return Random.nextInt(100).also { value ->
        writeToLog("getRandomInt() generated value $value")
    }
}

val i = getRandomInt()
println(i)
apply並also傳回上下文物件。
let、run、 並with回傳 lambda 結果。
您應該根據您接下來想要在程式碼中執行的操作仔細考慮您想要的回傳值。這可以幫助您選擇要使用的最佳範圍函數。
上下文對象
apply和的回傳值also是上下文物件本身。因此,它們可以作為輔助步驟包含在呼叫鏈中:您可以繼續在同一物件上一個接一個地連結函數呼叫。