自从前两年的I/O大会上,Google官方宣布Kotlin-first后,越来越多的Android由Java转向了Kotlin。而使用Kotlin常常要碰上标题中的这几个函数,它们之间有着相似的地方,但也有各自的不同。放在一起,横向对比,便于记忆,在此做个记录。
分类
这几个函数均来自kotlin-stdlib库中的Standard.kt文件,同样在这个文件中还有另外几个函数,一块说一说。
按照类型可以分为两类,一类是顶层函数,一类是扩展函数。
这几个函数的参数中,基本都有一个代码块参数block,T.() -> R
表示block的参数是T.this,(T) -> R
表示block的参数是T,也就是it。
顶层函数有:
1 | public inline fun TODO(): Nothing |
其中,TODO
是用来标记尚未实现的空方法,repeat
用来重复执行传入的action,这两个就不多说了,我们来对比一下with
和run
名称 | block参数 | 返回值 |
---|---|---|
run | 无 | block() |
with | T.this | block() |
扩展函数有:
1 | public inline fun <T, R> T.run(block: T.() -> R): R |
其中,takeIf
表示传入的predicate为true时,返回T,false返回null,而takeUnless
恰恰相反,false时返回T,true时返回null。
然后,我们来一块看一下剩下的4个函数。其实根据block的传入参数,和返回值的对比,区别就很清晰了。
传入参数有两种:T.this 和 T
返回值有两种:T 和 block()
两种传入参数和两种返回值,两两组合,就有了这4个函数
名称 | block参数 | 返回值 |
---|---|---|
run | T.this | block() |
apply | T.this | T |
let | T | block() |
also | T | T |
通过表格对比,就更加清晰了
应用
从传入参数来看,传T.this和T是类似的,传入T.this时,调用T的方法通过this.调用;传入T时,调用T的方法通过it.调用。
如果你不关心扩展函数的返回值,那么随便你用哪个,本质上的区别并不大。
如果关心扩展函数的返回值,当需要修改T中的一些成员的时候,考虑使用apply
和also
;当需要通过T来得到一个结果的时候,考虑使用run
和let
。
总结
这些个函数,都是Kotlin为了方便开发者写代码而设计的,如果你一个都不用,这完全没有问题。如果要用的话,就要清楚它们之间的区别和联系。