Kotlin let, run, also, apply, with

时间:2020-02-23 14:37:31  来源:igfitidea点击:

在本教程中,我们将实现Kotlin中提供的一些重要的标准库功能。
kotlin-stdlib为我们提供了实现惯用模式的有用的高阶函数。
我们将看到它们如何使Kotlin编程变得如此轻松和快捷。

我们将在下面讨论的功能是:

  • let
  • run
  • also
  • apply
  • with

Kotlin let

" let"将调用它的对象作为参数,并返回lambda表达式的结果。
Kotlin let是一个作用域函数,其中在表达式内部声明的变量不能在外部使用。

下面给出了一个演示kotlin let函数的示例。

fun main(args: Array<String>) {
  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进行null检查

另外,let对于检查Nullable属性很有用,如下所示。

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表达式内的代码。
因此,让我们也从if else null检查器中省下来!

Kotlin run

Kotlinrun是另一个有趣的功能。
下面的示例演示其用例。

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运行表达式可以更改外部属性。
因此,在上面的代码中,我们已针对本地范围重新定义了它。

  • 与let函数类似,run函数也返回last语句。

  • 与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 was null. Setting default value to: 
//Kotlin

Kotlin also

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

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

Kotlin let 和 also比较

以下代码片段显示了一个很好的示例,可以区分" let"和" also"。

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表达式则不返回任何值(单位),因为我们没有明确指定任何内容。

Kotlin apply

Kotlinapply是类型的扩展功能。
它在表达式中的对象引用(也称为接收器)上运行,并在完成时返回对象引用。

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

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

apply 和 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)

注意:在申请中不允许使用它。
如果数据类的属性名称在函数中是唯一的,则可以省略" 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"
  }

同样," with"与" apply"相似,除了一些区别。

Kotlin apply vs with

  • 没有对象(接收者)的运行,而应用则需要一个。

  • apply在对象引用上运行,而只是将其作为参数传递。

  • with函数的最后一个表达式返回结果。

var xyz = with(person)
  {
      name = "No Name"
      tutorial = "Kotlin tutorials"
      val xyz = "End of tutorial"
      xyz
  }
  println(xyz) //End of tutorial