在使用 kotlin 开发中,我们常常会使用到 let
、 run
、 with
、 apply
、 以及 also
这五个函数。它们的作用就是在对象的上下文中执行代码块。
在 Kotlin 中,这五个函数都可以在代码块的作用域中访问对象而无需其名称,因此它们被称为作用域函数
这五个函数主要的应用场景如下图所示,图片来源Google 工程师的推特帖子
可以看到这些函数基本上都执行同样的操作,即在一个对象上执行一个代码块。不同的是这个对象在代码块中如何使用,以及整个表达式的结果是什么。 。下面就详细介绍一下它们的区别:
函数原型上的区别
如果我们从函数原因上来看这五个作用域函数,可以讲它们分成三种,分别是:
- 函数原型为扩展函数,这一类有
let
、apply
、also
- 函数原型不是扩展函数,这一类有
with
- 以及既有扩展函数实现方式也有非扩展函数实现方式的
run
对于函数原型为扩展函数的 let
、apply
、also
来说,它们必须需要一个对象才能调用,代码如下:
kotlin
代码解读
复制代码
Person("Adam").apply {
age = 20
city = "London"
}
而对于函数原型非扩展函数的 with
来说,它可以直接被调用,代码示例如下:
kotlin
代码解读
复制代码
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
val firstItem = first()
val lastItem = last()
println("First item: $firstItem, last item: $lastItem")
}
而对于 run
,由于它有两种实现,因此上面两种方式都可以调用。
引用上下文对象的方式
run
、with
以及 apply
通过关键字 this
来引用上下文对象的。 而 let
及 also
则是通过 it
(默认情况下)来访问上下文对象的。最主要的区别是,在访问对象自身的属性时,this
可以省略,而 it
不可以,代码相对来说比较简洁。代码示例如下:
kotlin
代码解读
复制代码
Person("Adam").apply {
age = 20 // 等同于 this.age = 20
city = "London"
}
但是当上下文对象主要用作函数调用中的参数时,通过 it
访问上下文对象会更好。 在代码块中使用多个变量时,it
也更好一些。代码示例如下:
kotlin
代码解读
复制代码
fun getRandomInt(): Int {
return Random.nextInt(100).also {
writeToLog("getRandomInt() generated value $it")
}
}
返回值的区别
根据返回结果的不同,五个作用域函数可以分为以下两类:
apply
及also
:返回上下文对象自己let
、run
及with
:返回代码块的结果
代码示例如下:
kotlin
代码解读
复制代码
fun getRandomInt(): Int {
// 返回 int 自己
return Random.nextInt(100).also {
writeToLog("getRandomInt() generated value $it")
}
}
val numbers = mutableListOf("one", "two", "three")
// 返回代码块的结果
val countEndsWithE = numbers.run {
add("four")
add("five")
count { it.endsWith("e") }
}
小结
上文介绍了五个作用域函数在函数应用场景、函数原型、函数上下文对象、函数返回值这几个方面来比较上述作用域函数的不同点。五个作用域函数的不同点如下表所示:
函数 | 对象引用 | 返回值 | 是否是扩展函数 |
---|---|---|---|
let | it | Lambda 表达式结果 | 是 |
T.run{ } | this | Lambda 表达式结果 | 是 |
run{ } | - | Lambda 表达式结果 | 不是:调用无需上下文对象 |
with | this | Lambda 表达式结果 | 不是:把上下文对象当做参数 |
apply | this | 上下文对象 | 是 |
also | it | 上下文对象 | 是 |
参考
- Kotlin Standard Functions cheat-sheet | by Jose Alcérreca | Android Developers | Medium
- 作用域函数 · Kotlin 官方文档 中文版 (kotlincn.net)
作者:小墙程序员
链接:https://juejin.cn/post/7381657886802067456
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。