在 Kotlin 中,run 和 with 都是作用域函数(scope functions),它们允许以更简洁的方式操作对象。这两个函数的主要区别在于接收者和返回值的处理方式不同。下面我将详细解释 run 和 with 的用法,并通过具体的代码示例来说明它们的区别。
run
run 是一个扩展函数,它可以在任何类型的对象上调用。它的主要特点如下:
- 接收者:
this - 上下文对象:可以通过
this或省略前缀直接访问 - 返回值:
run块中的最后一行表达式的值或显式返回的值
run 示例:
data class Person(val name: String, var age: Int)
fun main() {
val person = Person("Alice", 30)
// 使用 run 修改对象属性并返回新值
val updatedAge = person.run {
age = 31
"Updated age of $name is now $age"
}
println(updatedAge) // 输出: Updated age of Alice is now 31
}
在这个例子中,run 被用来修改 person 对象的 age 属性,并返回一个描述更新结果的字符串。
with
with 不是一个扩展函数,而是一个顶层函数。它接受一个参数作为接收者,并在其内部执行代码块。其主要特点如下:
- 接收者:传入的对象
- 上下文对象:可以通过
this或省略前缀直接访问 - 返回值:
with块中的最后一行表达式的值或显式返回的值
with 示例:
data class Person(val name: String, var age: Int)
fun main() {
val person = Person("Bob", 25)
// 使用 with 修改对象属性并返回新值
val updatedAge = with(person) {
age = 26
"Updated age of $name is now $age"
}
println(updatedAge) // 输出: Updated age of Bob is now 26
}
在这个例子中,with 被用来修改 person 对象的 age 属性,并返回一个描述更新结果的字符串。
区别
-
调用方式:
run是一个扩展函数,可以直接在对象上调用。with是一个顶层函数,需要将对象作为参数传递给它。
-
返回值:
- 两者都返回代码块的最后一行表达式的值或显式返回的值。
-
使用场景:
- 如果需要在一个对象上执行一系列操作并且希望返回某个计算结果,
run是一个很好的选择。 - 如果已经有一个对象并且想要对它进行一系列操作,但不想改变该对象的引用,
with可能更适合。
- 如果需要在一个对象上执行一系列操作并且希望返回某个计算结果,
-
链式调用:
run支持链式调用,因为它可以返回任何类型的值,包括对象本身。with通常用于不需要链式调用的场景,因为它不是扩展函数,不能直接在对象上调用。
何时使用 run vs with
- 使用
run:当想在对象上调用方法、设置属性或执行一些逻辑,并且希望返回一个结果时。 - 使用
with:当已经有了一个对象,并且想在这个对象上执行多个操作,而不必每次都重复对象名时。
实际应用实例
假设我们有一个 StringBuilder 类型的对象,我们想添加一些文本并返回构建后的字符串:
使用 run:
val sb = StringBuilder()
val result = sb.run {
append("Hello")
append(" ")
append("World")
toString() // 返回构建后的字符串
}
println(result) // 输出: Hello World
使用 with:
val sb = StringBuilder()
val result = with(sb) {
append("Hello")
append(" ")
append("World")
toString() // 返回构建后的字符串
}
println(result) // 输出: Hello World
在这两个例子中,run 和 with 都可以实现相同的功能,但是由于 run 是扩展函数,它可以更自然地链式调用,而在 with 的情况下,需要明确地将对象作为参数传递给它。
通过合理地选择 run 和 with,可以使代码更加简洁、易读,并符合 Kotlin 的惯用法。
当前文章价值6.36元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

评论已关闭!