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

相关推荐
xuxie9937 分钟前
N11 ARM-irq
java·开发语言
wefly20171 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
luanma1509802 小时前
PHP vs C++:编程语言终极对决
开发语言·c++·php
寂静or沉默2 小时前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
kyriewen112 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript
娇娇yyyyyy3 小时前
QT编程(18): Qt QItemSelectionModel介绍
开发语言·qt
豆豆的java之旅3 小时前
软考中级软件设计师 数据结构详细知识点(含真题+练习题,可直接复习)
java·开发语言·数据结构
sthnyph3 小时前
QT开发:事件循环与处理机制的概念和流程概括性总结
开发语言·qt
大尚来也4 小时前
Java 反射:从“动态魔法”到生产实战的避坑指南
开发语言
无心水4 小时前
Java时间处理封神篇:java.time全解析
java·开发语言·python·架构·localdate·java.time·java时间处理