Kotlin 提供了许多有用的内置函数(scope functions),它们能在对象的上下文中执行代码块,让代码更简洁、表达力更强。主要的内置函数有以下几种:
五大主要作用域函数
1. let
// 使用 it 引用对象,返回最后一行结果
val result = object.let {
// 在此使用 it 操作对象
it.doSomething()
"返回值" // 返回这个
}
// 典型用途:空检查和转换
val length = nullableString?.let {
println(it) // 非空时才执行
it.length // 返回长度
}
2. run
// 使用 this 引用对象,返回最后一行结果
val result = object.run {
// 直接访问属性和方法(this.可省略)
property = "value"
doSomething()
"返回值"
}
// 也可以不基于对象使用
val result = run {
// 独立代码块
val a = 1
val b = 2
a + b
}
3. with
// 不是扩展函数,将对象作为参数传入
val result = with(object) {
// this 引用对象
property = "value"
doSomething()
"返回值"
}
4. apply
// 使用 this 引用对象,返回对象本身(链式调用)
val person = Person().apply {
// 对象配置
name = "John"
age = 25
city = "New York"
}
5. also
// 使用 it 引用对象,返回对象本身
val person = Person().also {
// 附加操作(如日志记录)
println("创建对象: $it")
it.initialize()
}
选择指南
| 函数 | 上下文对象 | 返回值 | 适合场景 |
|---|---|---|---|
| let | it | lambda 结果 | 空检查、数据转换 |
| run | this | lambda 结果 | 对象配置并计算结果 |
| with | this | lambda 结果 | 对已存在的对象进行批量操作 |
| apply | this | 对象本身 | 对象初始化、配置 |
| also | it | 对象本身 | 附加操作、日志记录 |
其他实用内置函数
takeIf / takeUnless
// 条件筛选
val number = input.takeIf { it.isNotEmpty() }?.toInt()
val result = value.takeUnless { it < 0 } // 除非条件成立,否则返回对象
// 链式使用
file.takeIf { it.exists() }?.let { readFile(it) }
repeat
// 重复执行
repeat(3) { index ->
println("执行第 ${index + 1} 次")
}
实际使用示例
data class User(var name: String, var age: Int)
fun processUser(user: User?) {
// 安全处理可空对象
user?.let { u ->
println("处理用户: ${u.name}")
u.age += 1
}
// 对象初始化
val newUser = User("", 0).apply {
name = "Alice"
age = 30
}
// 链式调用
newUser.also { println("创建用户: $it") }
.let { it to it.age > 18 } // 返回 Pair
.takeIf { it.second } // 只取成年用户
?.let { (user, _) ->
println("成年用户: ${user.name}")
}
}
最佳实践
- 避免过度嵌套:不要过度使用作用域函数导致代码难以阅读
- 保持简洁:如果 lambda 很简单,可以使用
it而不重命名 - 考虑可读性:选择让意图最清晰的函数
- 注意返回类型:
apply/also返回对象本身,其他返回 lambda 结果
这些内置函数让 Kotlin 代码更加函数式和声明式,大大减少了模板代码。