Kotlin ---作用域函数:run、let、also、apply、with

引言

在kotlin中第一句话 : 函数是第一公民,一切皆函数。

偶然间:看到一个名词作用域函数。字面意思: 在一个作用域内执行的函数。

查了资料看看概念:

Kotlin 标准库包含几个函数,它们的唯一目的是在对象的上下文中执行代码块

当对一个对象调用这样的函数并提供一个lambda表达式时,它会形成一个临时作用域。在此作用域中,可以访问该对象而无需其名称。这些函数称为作用域函数。

共有以下五种:letrunwithapply以及also

结论:

函数 对象引用 返回值 是否是扩展函数
let it Lambda表达式结果
run this Lambda表达式结果
run - Lambda表达式结果 不是:调用无需上下文对象
with this Lambda表达式结果 不是:把上下文对象当做参数
apply this 上下文对象
also it 上下文对象

用法:

  • 对一个非空(non-null)对象执行 lambda 表达式:let
  • 将表达式作为变量引入为局部作用域中:let
  • 对象配置:apply
  • 对象配置并且计算结果:run
  • 在需要表达式的地方运行语句:非扩展的 run
  • 附加效果:also
  • 一个对象的一组函数调用:with 不同作用域函数的使用场景存在重叠,可以根据项目或团队中使用的特定约定来选择使用哪些函数。

虽然作用域函数可以让代码更加简洁,但是要避免过度使用它们:这会使代码难以阅读并可能导致错误。

建议避免嵌套作用域函数,同时链式调用它们时要小心:因为很容易混淆当前上下文对象与thisit的值。

also

函数声明

Kotlin 复制代码
public inline fun <T> T.also(block: (T) -> Unit): T

also函数是对泛型 T 的扩展函数,接收一个参数类型为T、无返回值(返回值为Unit类型)的函数,且also函数的返回值就是调用者。

对于执行一些将上下文对象作为参数的操作很有用。

代码中看到 also 时,可以将其理解为并且用该对象执行以下操作。

例子:

Kotlin 复制代码
val alsoResult = book.also {
    it.changePrice(20)
    it.name = "alsoResult"
}
println("alsoResult $alsoResult")

结果: alsoResult Book(name=alsoResult, price=20)

apply

函数声明

Kotlin 复制代码
public inline fun <T> T.apply(block: T.() -> Unit): T

apply是泛型 T 的扩展函数,接收一个带有 T 类型接收者的无参、无返回值的函数,并且apply函数返回值就是 T 类型,也就是调用者的类型。

apply最常见的使用场景是用于对象配置。apply可以理解为将以下赋值操作应用于对象

Kotlin 复制代码
val applyResult = book.apply {
    changePrice(200)
    name = "applyResult"
}
println("applyResult $applyResult")

结果:applyResult Book(name=applyResult, price=200).

let

函数声明

Kotlin 复制代码
public inline fun <T, R> T.let(block: (T) -> R): R

let 是对泛型 T 的扩展函数,该扩展函数接收一个函数参数,并且函数参数的接收一个 T 类型的参数,且返回值是 R 类型,也是let这个扩展函数的返回值类型。

  • let 可用于在调用链的结果上调用一个或多个函数。
  • let 经常用于执行包含非空值代码块。如需对非空对象执行操作, 可对其使用安全调用操作符?.并调用 let 在 lambda 表达式中执行操作。

run

函数声明

Kotlin 复制代码
public inline fun <T, R> T.run(block: T.() -> R): R
public inline fun <R> run(block: () -> R): R

第一种,看起来就是把let中函数参数中的 T 类型参数改成了接收者类型,也是返回 R 类型;这和applyalso的区别是一样的。

with

函数声明

Kotlin 复制代码
public inline fun <T, R> with(receiver: T, block: T.() -> R): R

with并不是扩展函数,需要传入一个T 类型的receiver,可以在 block 中访问这个receiver的方法和属性.

  • 上下文对象作为接收者(this)使用。
  • 返回值是 lambda 表达式结果。

建议当不需要使用 lambda 表达式结果时,使用 with 来调用上下文对象上的函数。

with 可以理解为对于这个对象,执行以下操作.

Kotlin 复制代码
val withResult = with(book) {
    changePrice(300)
    name = "withResult"
    this //作为返回值
}
println("withResult $withResult")

结果:withResult Book(name=withResult, price=300)

结束。

相关推荐
weixin_462176418 分钟前
(三十一)深度解析领域特定语言(DSL)第六章——语法分析:递归下降语法分析器(Recursive-Descent Parser)
java·开发语言·软件构建
小刘同学++36 分钟前
C++11 alignas 和 alignof 关键字
开发语言·c++
未来之窗软件服务1 小时前
js调用微信支付 第二步 获取access_token ——仙盟创梦IDE
开发语言·javascript·微信·微信支付·仙盟创梦ide·东方仙盟
比特层递1 小时前
C++: 输出Windows平台或Linux平台时间信息的函数
开发语言·c++
蛋卷卷-1 小时前
【UE5】如何开发安卓项目的udp客户端
android·ue5·udp
大明者省1 小时前
量子跃迁:后大模型时代的颠覆者
开发语言·量子计算
froginwe112 小时前
HTML 媒体(Media)
开发语言
冰茶_2 小时前
C#中的QUIC实现
开发语言·c#
oioihoii2 小时前
C++11 Thread-Local Storage:从入门到精通
java·开发语言·c++
雨中散步撒哈拉2 小时前
3、做中学 | 二年级上期 Golang数据类型和常量/变量声明使用
开发语言·后端·golang