在 Kotlin 中,run
是一个作用域函数(scope function),用于在对象的上下文中执行代码块,并返回结果
一、run
作为扩展函数
语法 :对象.run { ... }
作用 :在对象的上下文中执行代码块,返回 lambda 的结果。
特点:
- 内部通过
this
访问对象(可省略)。 - 常用于链式调用或对对象进行转换操作。
示例:
kotlin
data class Person(var name: String, var age: Int)
fun main() {
val person = Person("Alice", 25)
val result = person.run {
// this 可以省略
name = "Bob" // 修改对象属性
age += 1
"姓名: $name, 年龄: $age" // 返回字符串
}
println(result) // 输出:姓名: Bob, 年龄: 26
println(person) // 输出:Person(name=Bob, age=26)
}
二、run
作为非扩展函数
语法 :run { ... }
作用 :直接执行代码块,返回 lambda 的结果,常用于需要临时作用域的场景。
特点:
- 无需对象即可调用。
- 适合在表达式需要的地方执行多行代码。
示例:
kotlin
fun main() {
val fullName = run {
val firstName = "John"
val lastName = "Doe"
"$firstName $lastName" // 返回拼接后的字符串
}
println(fullName) // 输出:John Doe
}
三、run
vs 其他作用域函数
函数 | 接收者 | 返回值 | 典型用途 |
---|---|---|---|
run |
this |
lambda 结果 | 对象初始化 + 计算返回值 |
let |
it |
lambda 结果 | 处理可空对象、链式操作 |
with |
this |
lambda 结果 | 非扩展版本,需传入对象参数 |
apply |
this |
对象本身 | 对象配置 |
also |
it |
对象本身 | 附加操作(如日志) |
四、使用场景
-
对象配置并计算结果
当需要修改对象属性并返回计算结果时,
run
非常高效:kotlinval personInfo = Person("Charlie", 30).run { age *= 2 "加倍年龄后: $age" }
-
链式调用中的中间操作
结合安全调用(
?.
)处理可空对象:perlval length = nullableString?.run { println("处理非空字符串: $this") length } ?: 0
-
替代临时变量
在需要表达式的地方替代临时变量:
inival discount = run { val basePrice = 100 val seasonMultiplier = 0.8 basePrice * seasonMultiplier }
-
把上一个结果值自动给下一个函数
kotlin
fun main() {
val str = "Lilei is OK"
// 下面是 具名函数 配合 run函数
// 这个是属于具名函数 str.run(具名函数)
str
.run(::isLong) // this == str本身
.run(::showText) // this == isLong返回的boolean值
.run(::mapText)
.run(::println)
println()
// let函数持有it,run函数持有this 都可以很灵活的,把上一个结果值 自动给 下一个函数
str.let(::isLong) // it == str本身
.let(::showText) // it == isLong返回的boolean值
.let(::mapText) // it == str本身
.let(::println) // it == str本身
println()
// >>>>>>>>>>>>>>>>>>>>>> 上面全部都是具名函数调用给run执行 下面全部是 匿名函数调 用给run执行
str
.run {
if (length > 5) true else false
}
.run {
if (this) "你的字符串合格" else "你的字符串不合格"
}
.run {
"【$this】"
}
.run {
println(this)
}
}
fun isLong(str: String) /* : Boolean */ = if (str.length > 5) true else false
fun showText(isLong: Boolean) /*: String */ = if (isLong) "你的字符串合格" else "你的字符串不合格"
fun mapText(getShow: String) /*: String */ = "【$getShow】"
五、总结
- 使用
对象.run
时,可以直接访问对象属性和方法(this
可省略)。 - 使用
run { ... }
(非扩展)时,适合快速生成一个作用域并返回结果。 - 根据是否需要返回值或操作对象本身,选择
run
、apply
或其他作用域函数。
通过灵活使用 run
,可以让代码更简洁且富有表达力。