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,不满足时返回对象本身

相关推荐
不吃香菜学java6 小时前
Redis的java客户端
java·开发语言·spring boot·redis·缓存
贵沫末7 小时前
python——打包自己的库并安装
开发语言·windows·python
文祐7 小时前
C++类之虚函数表及其内存布局(一个子类继承一个父类)
开发语言·c++
zuowei28897 小时前
华为网络设备配置文件备份与恢复(上传、下载、导出,导入)
开发语言·华为·php
xiaohe078 小时前
超详细 Python 爬虫指南
开发语言·爬虫·python
嗑嗑嗑瓜子的猫8 小时前
Java!它值得!
java·开发语言
xiaoshuaishuai88 小时前
C# GPU算力与管理
开发语言·windows·c#
lsx2024068 小时前
SVN 创建版本库
开发语言
xiaotao1318 小时前
01-编程基础与数学基石:Python错误与异常处理
开发语言·人工智能·python
皮卡蛋炒饭.9 小时前
线程的概念和控制
java·开发语言·jvm