每个作用域函数之间有两个主要区别:
- 引用上下文对象的方式
- 返回值
引用上下文对象的方式
run、with 以及** apply** 通过关键字 this 引用上下文对象,所以在他们的lambda表达式中可以向普通的类函数中一样访问上下文对象。因此,对于主要对对象成员进行操作(调用其函数或赋值其属性)的 lambda 表达式,建议将上下文对象作为接收者
val adam = Person("Adam").apply {
age = 20 // 和 this.age = 20 或者 adam.age = 20 一样
city = "London"
}
println(adam)
let 及 also 将上下文对象作为 lambda 表达式参数。如果没有指定参数名,对象可以用隐式默认名称 it 访问
fun getRandomInt(): Int {
return Random.nextInt(100).also { // 这里没有定义入参的名字所以就是it
writeToLog("getRandomInt() generated value $it")
}
}
val i = getRandomInt()
返回值
根据返回结果,作用域函数可以分为以下两类:
apply 及 also 返回上下文对象。
因此,它们可以作为辅助步骤包含在调用链中:你可以继续在同一个对象上进行链式函数调用。
val numberList = mutableListOf<Double>()
numberList.also { println("Populating the list") }
.apply {
add(2.71)
add(3.14)
add(1.0)
}
.also { println("Sorting the list") }
.sort()
let、run 及 with 返回 lambda 表达式结果.
在需要使用其结果给一个变量赋值,或者在需要对其结果进行链式操作等情况下,可以使用它们。
val numbers = mutableListOf("one", "two", "three")
val countEndsWithE = numbers.run {
add("four")
add("five")
count { it.endsWith("e") }
}
println("There are $countEndsWithE elements that end with e.")
let
- lambda表达式参数:上下文对象,it来访问
- 返回值: lambda表达式的结果
with
- 非扩展函数: 上下文对象作为参数传递,但是在 lambda 表达式内部,它可以作为接收者(this)使用
- 返回值: lambda表达式的结果
run
- lambada表达式参数: 上下文对象, this来访问 (不带参数的run,还可以作为非扩展函数)
- 返回值: lambda 表达式结果。
apply
- lambada表达式参数: 上下文对象,this来访问
- 返回值: 上下文本身
also
- lambada表达式参数: 上下文对象,it来访问
- 返回值: 上下文本身