标准函数是Kotlin中务必掌握的内容
let函数
let函数它主要用来解决什么问题的呢?还是看doWork这个函数,假设我们需要在study不为空的情况下调用很多study内部的函数,但受限于空指针检查,我们每个调用都需要使用?.
进行操作,为此我们可以使用let函数。
fun doWork(s: Study?) {
s?.doHomeWork()
s?.doReadBook()
}
fun doWork(s: Study?) {
s?.let({
s.doHomeWork()
s.doReadBook()
})
}
别忘记了,Lambda的时候我们提到过,如果Lambda表达式是方法的最后一个参数时且只有一个参数时可以省略括号:
fun doWork(s: Study?) {
s?.let {
s.doHomeWork()
s.doReadBook()
}
}
with函数
with函数接收两个参数,第一个参数是任意类型的对象,第二个参数是Lambda表达式,with函数会在Lambda表达式中提供第一个参数的上下文,并使用Lambda的最后一行代码作为返回值返回
val result = with(obj) {
// 这里是obj的上下文
"value" // with函数的返回值
}
那with函数是什么意思呢?举个例子:
比如有一个任务列表,现在我们完成所有任务,并将结果打印出来,正常的写法是这样的:
fun main() {
val list = listOf("a", "b", "c", "d", "e")
var res = StringBuffer()
res.append("开始完成任务...").append("\n")
for (s in list) {
res.append("正在完成任务: $s... \n")
}
res.append("任务已完成")
println(res)
}
如果使用with函数就可以精简成以下样子:
fun main() {
val list = listOf("a", "b", "c", "d", "e")
var res = with(StringBuffer()) {
append("开始完成任务...\n")
for (s1 in list) {
append("正在完成任务: $s1... \n")
}
append("任务完成")
}
println(res)
}
run函数
run函数的用法和使用场景其实和 with函数是非常类似的,只是稍微做了一些语法改动而已。首先run函数通常不会直接调用, 而是要在某个对象的基础上调用;其次run函数只接收一个Lambda参数,并且会在Lambda表 达式中提供调用对象的上下文。其他方面和with函数是一样的,包括也会使用Lambda表达式 中的最后一行代码作为返回值返回。示例代码如下:
val result = obj.run {
// 这里是obj的上下文
"value" // run函数的返回值
}
如果将刚刚例子转到run上就是这样的:
fun main() {
val list = listOf("a", "b", "c", "d", "e")
val res = StringBuffer().run {
append("开始完成任务...\n")
for (s1 in list) {
append("正在完成任务: $s1... \n")
}
append("任务完成")
}
println(res)
}
总体来说变化非常小,只是将调用with函数并传入StringBuilder对象改成了调用 StringBuilder对象的run方法,其他都没有任何区别,这两段代码最终的执行结果是完全相 同的。
apply函数
apply函数和run函数也是极其类似的,都要在某 个对象上调用,并且只接收一个Lambda参数,也会在Lambda表达式中提供调用对象的上下 文,但是apply函数无法指定返回值,而是会自动返回调用对象本身。示例代码如下:
val result = obj.apply {
// 这里是obj的上下文
}
// result == obj
fun main() {
val list = listOf("a", "b", "c", "d", "e")
val res = StringBuffer().apply {
append("开始完成任务...\n")
for (s1 in list) {
append("正在完成任务: $s1... \n")
}
append("任务完成")
}
println(res)
}
also函数
also函数允许你在链式调用中执行其他副作用操作 (例如打印日志) 而不会影响原始对象
fun main() {
val n = mutableListOf("a", "b", "c", "a", "b", "c")
val m = n
.filter {
it == "a" }
.also {
println(it) }
.toList()
println(m)
}
输出结果:
[a, a]
[a, a]
takeIf函数
takeIf函数和takeUnless函数用途相似, 可以用于条件检查,返回满足条件的值,否则返回 null
。
fun main() {
val n = 5
val r = n.takeIf {
it > 0 } ?: "Number is not positive"
println(r)
val k = n.takeUnless {
it > 0 } ?: "Number is positive"
println(k)
}
输出结果:
5
Number is positive
runCatching函数
runCatching
是一个用于捕获异常的函数,非常简洁,可以避免显式的 try-catch
语句。它返回一个 Result
对象,便于链式调用。
val result = runCatching {
"123".toInt() // 成功解析为整数
}.getOrElse {
-1 } // 如果解析失败则返回 -1
println(result) // 输出: 123
use函数
use
函数通常用于资源管理,它确保资源在使用后会被正确关闭。这类似于 Java 的 try-with-resources
机制,用于处理 Closeable
对象,比如文件、网络流等。
val file = File("example.txt")
file.bufferedReader().use {
reader ->
println(reader.readLine())
}