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

相关推荐
寻寻觅觅☆6 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
l1t7 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
赶路人儿7 小时前
Jsoniter(java版本)使用介绍
java·开发语言
ceclar1238 小时前
C++使用format
开发语言·c++·算法
码说AI8 小时前
python快速绘制走势图对比曲线
开发语言·python
Gofarlic_OMS8 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
星空下的月光影子8 小时前
易语言开发从入门到精通:补充篇·网络爬虫与自动化采集分析系统深度实战·HTTP/HTTPS请求·HTML/JSON解析·反爬策略·电商价格监控·新闻资讯采集
开发语言
老约家的可汗8 小时前
初识C++
开发语言·c++
wait_luky8 小时前
python作业3
开发语言·python
消失的旧时光-19439 小时前
第十九课:为什么要引入消息队列?——异步系统设计思想
java·开发语言