Kotlin 中作用域函数的使用
- Kotlin 中的作用域函数
- 在 Kotlin 中使用范围函数
-
在 Kotlin 中使用
also
范围函数 -
在 Kotlin 中使用
let
作用域函数 -
在 Kotlin 中使用
apply
范围函数 -
在 Kotlin 中使用
run
作用域函数 -
在 Kotlin 中使用
with
作用域函数
本文将讨论 Kotlin 中的作用域函数 also
。我们还将介绍 Kotlin 中可用的其他作用域函数。
但首先,让我们了解什么是作用域函数。
Kotlin 中的作用域函数
Kotlin 有许多专门为在对象上下文中执行一段代码而创建的函数。这些函数称为作用域函数。
当我们使用 lambda 表达式调用时,作用域函数会为对象创建一个临时作用域。Kotlin 中有 5 个作用域函数,分别是 also
、let
、apply
、run
和 with
。
虽然 Kotlin 中的所有作用域函数都执行相同的功能,但不同之处在于该块内的对象在执行后如何可用。根据返回值和对象引用,我们需要选择五个作用域函数之一。
下表显示了每个作用域函数的对象引用和返回值。
范围函数 | 对象参考 | 返回值 | 扩展函数 |
---|---|---|---|
also |
it |
兰姆达值 | 它是一个扩展函数。 |
let |
this |
兰姆达值 | 它是一个扩展函数。 |
apply |
- | 兰姆达值 | 它不是一个扩展函数。 |
run |
this |
兰姆达值 | 它不是一个扩展函数。 |
run |
this |
上下文对象 | 它是一个扩展函数。 |
with |
it |
上下文对象 | 它是一个扩展函数。 |
在 Kotlin 中使用范围函数
下面的示例演示了在 Kotlin 中使用范围函数。在这段代码中,我们将使用 let
函数为对象 Students 创建范围。
data class Student(var firstName: String, var lastName: String, var age: Int, var address: String) {
fun moving(newAddress: String) { address = newAddress }
fun ageIncrease() { age++ }
}
fun main() {
Student("David", "Miller", 24, "New York").let {
println(it)
it.moving("Chicago")
it.ageIncrease()
println(it)
}
}
输出:
范围函数在输出中将 Student 对象称为 it
。如果不使用作用域函数,我们将不得不声明一个新变量并使用 Student 对象的值对其进行初始化以访问它。
在 Kotlin 中使用 also
范围函数
如上表所述,Kotlin 中的 also
函数提供了一个上下文对象作为参数 (it
)。当我们需要执行将上下文对象作为任何函数的参数的操作时,我们可以使用 also
。
在 Kotlin 中使用 also
的另一个好方法是当我们需要直接引用对象本身而不是其属性或函数时。参考下面的例子来理解 Kotlin 中的 also
函数。
fun main() {
val numList = mutableListOf("one", "three", "five")
numList
.also { println("Elements in the list before adding a new one: $it") }
.add("seven")
println("Elements in the list after adding a new one: " + numList)
}
输出:
在 Kotlin 中使用 let
作用域函数
Kotlin 中的 let
范围函数提供上下文对象作为参数 it
。它的返回值是 lambda 执行的结果。
我们可以使用 let
函数调用多个函数来累积调用链的结果。
fun main() {
val numList = mutableListOf("one", "three", "five", "seven", "nine")
val resList = numList.map { it.length }.filter { it > 3 }
println(resList)
}
输出:
[5,4,5,4]
我们可以使用 let
范围函数来打印 lambda 结果,而不是在上面的示例中使用 resList
。
fun main() {
val numList = mutableListOf("one", "three", "five", "seven", "nine")
numList.map { it.length }.filter { it > 3 }.let{
println(it)
//We can add more functions here
}
}
输出:
[5,4,5,4]
如果代码只有一个函数,我们可以将 lambda (it
) 替换为方法引用符号 (::
)。
fun main() {
val numList = mutableListOf("one", "three", "five", "seven", "nine")
numList.map { it.length }.filter { it > 3 }.let(::println)
}
输出:
[5,4,5,4]
在 Kotlin 中使用 apply
范围函数
在 Kotlin (this
) 中使用 apply
函数时,上下文对象可用作接收器。我们可以在没有任何返回值的代码块上使用 apply
函数。
最常见的用例是在对象配置期间。参考下面的示例,我们创建了一个 Student 对象,然后对其进行配置。
data class Student(var Name: String, var age: Int = 0, var address: String = "")
fun main() {
val david = Student("David Miller").apply {
age = 24
address = "New York"
}
println(david)
}
输出:
在 Kotlin 中使用 run
作用域函数
在 Kotlin 中使用 run
函数时,我们将上下文对象作为接收者 (this
)。lambda 执行结果本身就是这个作用域函数的返回值。
当 lambda 同时具有对象初始化和返回值的计算时,run
函数最有用。
class port(var url: String, var portNum: Int) {
fun initialRequest(): String = "Initial default request"
fun res(request: String): String = "This is the result of query '$request'"
}
fun main() {
val portService = port("https://example.kotlinlang.org", 80)
val finalResult = portService.run {
portNum = 8080
res(initialRequest() + " to port $portNum")
}
// the same code written with let() function:
val letResult = portService.let {
it.portNum = 8080
it.res(it.initialRequest() + " to port ${it.portNum}")
}
println(finalResult)
println(letResult)
}
输出:
我们也可以在 Kotlin 中使用 run
作为非扩展函数。这意味着它将执行一个需要表达式的语句块。
fun main() {
val hexNum = run {
val dig = "0-9"
val hexDig = "A-Fa-f"
val indication = "+-"
Regex("[$indication]?[$dig$hexDig]+")
}
for (match in hexNum.findAll("+139 -ABFF 79")) {
println(match.value)
}
}
输出:
+139
-ABFF
79
在 Kotlin 中使用 with
作用域函数
with
函数也是一个非扩展函数,例如 run
。with
函数的特点是它作为参数传递但可作为接收器使用。
with
最适合在我们不想提供 lambda 结果的上下文对象上调用函数。
fun main() {
val num = mutableListOf("one", "three", "five", "seven")
with(num) {
println("The function 'with' is called with argument $this")
println("The function contains $size items")
}
}
输出:
Kailash Vaviya is a freelance writer who started writing in 2019 and has never stopped since then as he fell in love with it. He has a soft corner for technology and likes to read, learn, and write about it. His content is focused on providing information to help build a brand presence and gain engagement.
LinkedIn