1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
class Test {
data class Man(val name: String, val argOne: String = "456")
private val argOne = "123"
fun print() {
Man("stefan").let {
println(it.name) // it 代表 let 的调用方: Man
println(this.argOne) //123 this 代表 print 方法的属主: class Test
println(argOne) //456 隐式调用 this 同上一行
println(it.argOne) //456
}
Man("stefanJ").run {
println(this.name) // this 代表 run 的调用方: Man
println(this.argOne) //456
println(argOne) //456 隐式调用 this,所以是 Man 中的 argOne
}
Man("stefanJi").apply {
println(this.name) // this 代表 apply 的调用方: Man
println(this.argOne) //456
println(argOne) //456 隐式调用 this
}
with(Man("stefanJiJ")) {
println(this.name) // this 代表 with 接收的对象
println(this.argOne) //456
println(argOne) //456
}
}
}
|
从上面的例子可以看出,let
run
apply
他们的本质区别是代码块里的能拿到的执行对象不一样:
let
是通过it
拿到当前执行对象
run
通过this
apply
通过this
但是 run
和 apply
貌似没有差别,既然名字不一样,肯定还是有差别的,看看他们的签名:
1
2
3
4
|
public inline fun <T, R> T.run(block: T.() -> R): R {
//... 忽略中间部分
return block()
}
|
run 的返回值是代码块的返回值
1
2
3
4
5
|
public inline fun <T> T.apply(block: T.() -> Unit): T {
//... 忽略中间部分
block()
return this
}
|
apply 的返回值是当前对象
1
2
3
4
|
public inline fun <T, R> T.let(block: (T) -> R): R {
//... 忽略中间部分
return block(this)
}
|
let 的返回值也是代码块的返回值,且会把当前对象作为参数传入,这个参数默认名字叫 it
,也可以自己取名字
1
2
3
4
5
6
|
Man("stefan").let { man ->
println(man.name) // man 代表 let 的调用方: Man
println(this.argOne) //123 this 代表 print 方法的属主: class Test
println(argOne) //456 隐式调用 this 同上一行
println(man.argOne) //456
}
|
1
2
3
4
|
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
//... 忽略中间部分
return receiver.block()
}
|
而且 let
run
apply
都是 T.xx
的方式定义,说明他们是作为任意对象的一个扩展函数使用,而with
则是作为普通的顶层函数使用。