Kotlin let run apply with 方法

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

但是 runapply 貌似没有差别,既然名字不一样,肯定还是有差别的,看看他们的签名:

  • run
1
2
3
4
public inline fun <T, R> T.run(block: T.() -> R): R {
//... 忽略中间部分
return block()
}

run 的返回值是代码块的返回值

  • apply
1
2
3
4
5
public inline fun <T> T.apply(block: T.() -> Unit): T {
//... 忽略中间部分
block()
return this
}

apply 的返回值是当前对象

  • let
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
}

  • with
    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则是作为普通的顶层函数使用。

赏杯咖啡 🍵 Donate