两个主要区别
this和it是作用域函数获取对象引用的 短名称, 两者都提供相同的功能
范围函数: run,with,apply 使用this
在大多数情况下,this访问接收器对象的成员时可以省略,从而使代码更短
data class Person(var name: String, var age: Int = 0, var city: String = "")
fun main() {
val adam = Person("Adam").apply {
age = 20 // same as this.age = 20 or adam.age = 20
city = "London"
}
}
但是不加this,就不容易区分age、city是来自内部接收器Person 还是 外部成员或功能
data class Person(var name: String, var age: Int = 0, var city: String = "")
var otherName = "wangxueming"
fun main() {
val adam = Person("Adam").apply {
age = 20 // same as this.age = 20 or adam.age = 20
city = "London"
otherName = "wxm"
}
println("age = ${adam.age}; city = ${adam.city}; otherName = ${otherName}")
}
这里的otherName你就不容易看出来到底是Person的变量还是外部变量。
范围函数: let,also使用it
import kotlin.random.Random
fun writeToLog(message: String) {
println("INFO: $message")
}
fun main() {
fun getRandomInt(): Int {
return Random.nextInt(100).also {
writeToLog("getRandomInt() generated value $it")
//下面这行的this会报编译错误:'this' is not defined in this context
//writeToLog("getRandomInt() generated value $this")
}
}
val i = getRandomInt()
}
it在lambda中是支持自定义名称的
将上个范例中的getRandomInt(),从it改成value
fun getRandomInt(): Int {
return Random.nextInt(100).also { value -> {
writeToLog("getRandomInt() generated value $value")
writeToLog("getRandomInt() generated 222 value $value")
}
}
}
apply、also返回上下文对象
let、run、with返回lambda结果
apply、also会返回 上下文对象;
但apply、also发起者是 上下文对象;
这就是个链式调用嘛,准确的是是对fun的链式调用
fun main() {
val numberList = mutableListOf()
numberList.also { println("Populating the list") }
.apply {
add(2.71)
add(3.14)
add(1.0)
}
.also { println("Sorting the list") }
.sort()
println(numberList)
}
进一步理解一下,in是上下文对象,out依旧是上下文对象
这说明 also和apply不对原先的操作造成任何影响
原来的是fun,添加了also或apply之后,返回的依旧是fun
also、apply可以理解为对原先 fun的补充逻辑处理
import kotlin.random.Random
fun writeToLog(message: String) {
println("INFO: $message")
}
fun main() {
fun getRandomInt(): Int {
return Random.nextInt(100).also {
writeToLog("getRandomInt() generated value $it")
}
}
val i = getRandomInt()
}
添加also之后,Random.nextInt(100)不受影响,只是额外打印了一行log
这就可以动态的 给fun添加一个原先fun处理完成后的逻辑
let、run、with会返回 lambda表达式结果
这就提供了 将fun计算的结果传给下一个函数继续计算
这是对结果的链接调用
fun main() {
val numbers = mutableListOf("one", "two", "three")
val countEndsWithE = numbers.run {
add("four")
val Res1 = count { it.startsWith("f") }
println("Res1 = ${Res1}")
add("five")
val Res2 = count { it.startsWith("f") }
println("Res2 = ${Res2}")
println("${numbers}")
count { it.endsWith("e")&&it.startsWith("t") }
}
println("There are $countEndsWithE elements that end with e.")
}
输出结果为
Res1 = 1
Res2 = 2
[one, two, three, four, five]
There are 1 elements that end with e.
正如文章开头说的,作用于表达式 只是书写的简化
相当于是 多行 逻辑处理的整合
每一行代码都能依次执行,并及时的得到相应的结果
功能 | 对象参考 | 返回值 | 是扩展功能 | 适用情况 |
---|---|---|---|---|
let | it | Lambda结果 | 是 | 仅支持在非null对象上使用;将 表达式 像变量一样引入到 作用域中 |
run | this | Lambda结果 | 是 | 对象配置和计算结果 |
run | – | Lambda结果 | 否:在没有上下文对象的情况下调用 | 需要表达式的运行语句 |
with | this | Lambda结果 | 否:将上下文对象作为参数。 | 对对象进行分组功能调用 |
apply | this | 上下文对象 | 是 | 对象配置 |
also | it | 上下文对象 | 是 | 附加功能 |