标准函数是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)}
输出结果:
5Number is positive
runCatching函数
runCatching
是一个用于捕获异常的函数,非常简洁,可以避免显式的 try-catch
语句。它返回一个 Result
对象,便于链式调用。
val result = runCatching { "123".toInt() // 成功解析为整数}.getOrElse { -1 } // 如果解析失败则返回 -1println(result) // 输出: 123
use函数
use
函数通常用于资源管理,它确保资源在使用后会被正确关闭。这类似于 Java 的 try-with-resources
机制,用于处理 Closeable
对象,比如文件、网络流等。
val file = File("example.txt")file.bufferedReader().use { reader -> println(reader.readLine())}