Kotlin let、run、also、apply、with

在這個教程中,我們將實現 Kotlin 中提供的一些重要標準庫函數。kotlin-stdlib 為我們提供了一些有用的高階函數,實現了慣用模式。我們將看到它們如何使 Kotlin 編程變得更加輕鬆和快速。我們將討論以下函數:

  • let
  • run
  • also
  • apply
  • with

Kotlin let

let 接受其調用對象作為參數並返回 Lambda 表達式的結果。Kotlin let 是一個作用域函數,在表達式內聲明的變量在外部無法使用。下面給出了演示 kotlin let 函數的示例。

fun main(args: Array) {
    var str = "Hello World"
    str.let { println("$it!!") }
    println(str)

}
//Prints
//Hello World!!
//Hello World

it 關鍵字包含在 let 內的屬性副本。從 let 返回的最後一個值將作為參數返回,如下所示。

var strLength = str.let { "$it function".length }
println("strLength is $strLength") //prints strLength is 25

鏈接 let 函數

var a = 1
var b= 2

a = a.let { it + 2 }.let { val i = it + b
        i}
println(a) //5

正如您所看到的,我们在第二个 let 函数内部声明了一个本地变量 “i”。将 let 函数的最后一条语句设置为 i 将该属性返回到外部属性 a

嵌套 let

我们可以在另一个 let 表达式内部设置一个 let 表达式,如下所示。

var x = "Anupam"
x.let { outer -> outer.let { inner -> print("Inner is $inner and outer is $outer") } }

//Prints
//Inner is Anupam and outer is Anupam

对于嵌套的 let,我们不能使用 it 关键字。我们需要在两个 let 函数中为 it 分配显式名称。只有最外层的 let 返回值如下所示。

var x = "Anupam"
    x = x.let { outer ->
        outer.let { inner ->
            println("Inner is $inner and outer is $outer")
            "Kotlin Tutorials Inner let"
        }
        "Kotlin Tutorials Outer let" 
    }
    println(x) //prints Kotlin Tutorials Outer let

用于空值检查的 let

此外,let 对于检查 可空属性也很有用,如下所示。

var name : String? = "Kotlin let null check"
name?.let { println(it) } //prints Kotlin let null check
name = null
name?.let { println(it) } //nothing happens

仅当属性不为 null 时才执行 let 表达式中的代码。因此,let 也使我们免于使用 if else null 检查器的困扰!

Kotlin run

Kotlin run 是另一个有趣的函数。以下示例演示了其用法。

var tutorial = "This is Kotlin Tutorial"
    println(tutorial) //This is Kotlin Tutorial
    tutorial = run {
        val tutorial = "This is run function"
        tutorial
    }
    println(tutorial) //This is run function

Kotlin 的 run 表达式可以更改外部属性。因此,在上面的代码中,我们已将其重新定义为局部范围。

  • 与 let 函数类似,run 函数也会返回最后一个语句。
  • 与 let 不同,run 函数不支持 it 关键字。

let 和 run

让我们将 let 和 run 函数结合起来使用。

var p : String? = null
    p?.let { println("p is $p") } ?: run { println("p was null. Setting default value to: ")
        p = "Kotlin"}

    println(p)
//Prints
//p 为空。将默认值设置为: 
//Kotlin

Kotlin 也

顾名思义,also 表达式对其调用的对象执行一些附加处理。与 let 不同,它返回原始对象而不是任何新的返回数据。因此,返回的数据始终具有相同的类型。像 let 一样,also 也使用 it

var m = 1
m = m.also { it + 1 }.also { it + 1 }
println(m) //prints 1 

Kotlin let vs also

以下代碼片段展示了區分 letalso 的一個很好的示例。

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

var l = person.let { it.tutorial = "Android" }
var al = person.also { it.tutorial = "Android" }
    
println(l)
println(al)
println(person)

在上面的代碼中,我們使用了 資料類別。also 表達式返回資料類別物件,而 let 表達式返回什麼都沒有(Unit),因為我們沒有明確指定任何東西。

Kotlin apply

Kotlin apply 是一個對類型的擴展函數。它在對象引用(也稱為接收者)上運行到表達式完成並返回對象引用。

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

person.apply { this.tutorial = "Swift" }
println(person)

apply vs also

data class Person(var n: String, var t : String)
var person = Person("Anupam", "Kotlin")

person.apply { t = "Swift" }
println(person)

person.also { it.t = "Kotlin" }
println(person)

注意:在 apply 中不允許使用 it。如果資料類別的屬性名稱在函數中是唯一的,則可以省略 this。我們應該只在不想要遮蔽 this 時使用 also

Kotlin 中的 with

apply 一样,with 用于在不需要每次调用引用上的点运算符的情况下更改实例属性。

data class Person(var name: String, var tutorial : String)
var person = Person("Anupam", "Kotlin")

with(person)
    {
        name = "No Name"
        tutorial = "Kotlin tutorials"
    }

apply 类似,with 也有一些不同之处。

Kotlin apply vs with

  • with 在没有对象(接收者)的情况下运行,而 apply 需要一个对象。
  • apply 在对象引用上运行,而 with 只是将其作为参数传递。
var xyz = with(person)
    {
        name = "No Name"
        tutorial = "Kotlin tutorials"
        val xyz = "End of tutorial"
        xyz
    }
    println(xyz) //End of tutorial

with 函数的最后一个表达式返回结果。这就是 Kotlin 标准函数用于在函数内部修改变量或修改对象的所有内容。

Source:
https://www.digitalocean.com/community/tutorials/kotlin-let-run-also-apply-with