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
//内部是Anupam,外部是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的空值检查器!

Kotlin运行

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 相似,但也有一些区别。

Kotlin apply 与 with

  • with 在没有对象(接收器)的情况下运行,而 apply 需要一个。
var xyz = with(person)
    {
        name = "No Name"
        tutorial = "Kotlin tutorials"
        val xyz = "End of tutorial"
        xyz
    }
    println(xyz) //End of tutorial

apply 在对象引用上运行,而 with 只是将其作为参数传递。 with 函数的最后一个表达式返回一个结果。这就是用于在函数内更改变量或修改对象的 Kotlin 标准函数的全部内容。

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