返回

Kotlin 作用域函数之 let、with、run、also、apply 深入浅出

Android

前言

在 Kotlin 语言中,作用域函数是一组用于在对象的上下文中执行代码块的函数。它们可以简化代码,使代码更具可读性和简洁性。Kotlin 标准库包含了几个作用域函数,包括 let、with、run、also 和 apply。本文将深入浅出地介绍这五个作用域函数的用法和异同,帮助您理解这些函数背后的概念并灵活应用它们以编写更简洁、更具可读性的 Kotlin 代码。

作用域函数概述

作用域函数的主要作用是允许您在某个对象的上下文中执行代码块。当您对一个对象调用一个作用域函数并提供一个 lambda 表达式时,会形成一个临时作用域。在此作用域中,您可以访问该对象而无需对其进行显式引用。这可以简化代码并使代码更具可读性。

let 函数

let 函数用于在某个对象的上下文中执行代码块,并将代码块的返回值作为结果返回。它非常适合用于对某个对象进行一次性操作的情况。

val list = listOf(1, 2, 3)
val sum = list.let { it.sum() }
println(sum) // 输出:6

在上面的示例中,let 函数被用于对 list 对象进行一次性求和操作。代码块 it.sum() 在 list 对象的上下文中执行,并将求和结果作为结果返回。

with 函数

with 函数与 let 函数非常相似,但它不是将代码块的返回值作为结果返回,而是将代码块本身作为结果返回。这使得它非常适合用于对某个对象进行多次操作的情况。

val list = listOf(1, 2, 3)
with(list) {
    forEach { println(it) }
    println(sum())
}

在上面的示例中,with 函数被用于对 list 对象进行多次操作。代码块 forEach { println(it) } 和 println(sum()) 都在 list 对象的上下文中执行。

run 函数

run 函数与 with 函数非常相似,但它有一个重要的区别。run 函数总是将代码块的返回值作为结果返回,即使代码块没有显式返回任何值。

val list = listOf(1, 2, 3)
val sum = list.run {
    forEach { println(it) }
    sum()
}
println(sum) // 输出:6

在上面的示例中,run 函数被用于对 list 对象进行多次操作。代码块 forEach { println(it) } 和 sum() 都在 list 对象的上下文中执行。即使 sum() 函数没有显式返回任何值,run 函数仍然将它的返回值作为结果返回。

also 函数

also 函数用于在某个对象的上下文中执行代码块,但不会将代码块的返回值作为结果返回。它非常适合用于对某个对象进行一些修改或操作的情况。

val list = listOf(1, 2, 3)
val newList = list.also { it.add(4) }
println(newList) // 输出:[1, 2, 3, 4]

在上面的示例中,also 函数被用于对 list 对象进行修改。代码块 it.add(4) 在 list 对象的上下文中执行,并将 4 添加到 list 中。also 函数本身不会返回任何值,但它会返回 list 对象本身。

apply 函数

apply 函数与 also 函数非常相似,但它有一个重要的区别。apply 函数总是将代码块的返回值作为结果返回,即使代码块没有显式返回任何值。

val list = listOf(1, 2, 3)
val newList = list.apply {
    add(4)
    removeAt(0)
}
println(newList) // 输出:[2, 3, 4]

在上面的示例中,apply 函数被用于对 list 对象进行修改。代码块 add(4) 和 removeAt(0) 都在 list 对象的上下文中执行。即使 removeAt(0) 函数没有显式返回任何值,apply 函数仍然将它的返回值作为结果返回。

比较

下表总结了 let、with、run、also 和 apply 这五个作用域函数的异同:

函数 返回值 可变性
let 代码块的返回值 不可变
with 代码块本身 不可变
run 代码块的返回值 可变
also 对象本身 可变
apply 代码块的返回值 可变

结语

Kotlin 作用域函数为我们提供了在对象的上下文中执行代码块的便捷方式。它们可以简化代码,使代码更具可读性和简洁性。通过理解这些函数的用法和异同,您可以灵活应用它们以编写更简洁、更具可读性的 Kotlin 代码。