kotlin作用域函数 let、run、with、also、apply

kotlin v2.3.0 官方文档https://kotlinlang.org/docs/scope-functions.html

参考官方文档,仅作学习记录用

几个函数作用类似,区别在于对对象的引用以及返回结果

|-------|------|----------------------|---------|
| 函数 | 对象引用 | 返回值 | 是否为扩展函数 |
| let | it | lambada result | yes |
| run | this | lambada result | yes |
| run | - | lambada result | no |
| with | this | ambada result | no |
| apply | this | context object(this) | yes |
| also | it | context object(this) | yes |

选择的简单指南:

非空判断:let

在局部范围内引入表达式作为变量:let

对象配置:apply

对象配置以及计算结果:run

需要表达式的运行语句(非扩展):run

附加效果:also

对对象进行分组函数调用:with

let :

上下文对象作为参数it,返回结果为lambda表达式结果(最后一行)

通常用在非空判断、引入局部变量便于代码阅读

Kotlin 复制代码
//非空判断
val str: String? = "Hello"   
//processNonNullString(str)       // compilation error: str can be null
val length = str?.let { 
    println("let() called on $it")        
    processNonNullString(it)      // OK: 'it' is not null inside '?.let { }'
    it.length
}

//局部变量
val numbers = listOf("one", "two", "three", "four")
val modifiedFirstItem = numbers.first().let { firstItem ->
    println("The first item of the list is '$firstItem'")
    if (firstItem.length >= 5) firstItem else "!" + firstItem + "!"
}.uppercase()
println("First item after modifications: '$modifiedFirstItem'")

with:(可以理解为 " with this object, do the following. "

上下文对象用作lambda接收器(this),返回结果为lambda表达式结果(最后一行)

当不需要使用返回的结果时,建议使用with来调用上下文对象上的函数

Kotlin 复制代码
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
    println("'with' is called with argument $this")
    println("It contains $size elements")
}

另外也可以用with 根据 对象的属性或者方法计算出的结果 构建引用

Kotlin 复制代码
val numbers = mutableListOf("one", "two", "three")
val firstAndLast = with(numbers) {
    "The first element is ${first()}," +
    " the last element is ${last()}"
}
println(firstAndLast)

run:

上下文对象用作lambda接收器(this),返回结果为lambda表达式结果(最后一行)

run与with类似,但可以作为扩展函数使用,更像let,推荐当需要初始化对象并计算返回值时使用

Kotlin 复制代码
val service = MultiportService("https://example.kotlinlang.org", 80)

val result = service.run {
    port = 8080
    query(prepareRequest() + " to port $port")
}

// the same code written with let() function:
val letResult = service.let {
    it.port = 8080
    it.query(it.prepareRequest() + " to port ${it.port}")
}

也可以作为非扩展函数使用,可以理解为: " run the code block and compute the result. "

Kotlin 复制代码
val hexNumberRegex = run {
    val digits = "0-9"
    val hexDigits = "A-Fa-f"
    val sign = "+-"

    Regex("[$sign]?[$digits$hexDigits]+")
}

for (match in hexNumberRegex.findAll("+123 -FFFF !%*& 88 XYZ")) {
    println(match.value)
}

apply:

上下文对象用作lambda接收器(this),返回对象本身

推荐在不需要返回值并且对对象的属性进行操作时使用,最推荐的使用场景为对象初始化和配置

可以理解为" apply the following assignments to the object. "

Kotlin 复制代码
val adam = Person("Adam").apply {
    age = 32
    city = "London"        
}
println(adam)

另外一个使用场景是包含在多个调用链中,以进行更复杂的处理

Kotlin 复制代码
val numberList = mutableListOf<Double>()
numberList.also { println("Populating the list") }
    .apply {
        add(2.71)
        add(3.14)
        add(1.0)
    }
    .also { println("Sorting the list") }
    .sort()

also:(可以理解为" and also do the following with the object. ")

上下文对象作为参数it,返回对象本身

通常用于引用该对象作为参数时使用,

也可用于执行一些将上下文对象作为参数的操作,用于需要引用对象而不是其属性和函数的操作,或者不想在外部使用this引用时。

Kotlin 复制代码
val numbers = mutableListOf("one", "two", "three")
numbers
    .also { println("The list elements before adding new one: $it") }
    .add("four")

takeIf与takeUnless:

takeIf满足条件时返回对象本身,不满足时返回null

takeUnless满足条件时返回null,不满足时返回对象本身

相关推荐
Kapaseker17 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
Kapaseker2 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
FunnySaltyFish2 天前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Kapaseker3 天前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
Kapaseker4 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
A0微声z6 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin
alexhilton6 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
lhDream6 天前
Kotlin 开发者必看!JetBrains 开源 LLM 框架 Koog 快速上手指南(含示例)
kotlin
RdoZam6 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
Kapaseker7 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin