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)

结束。

相关推荐
张小潇1 小时前
AOSP15 Input专题InputDispatcher源码分析
android
TT_Close1 小时前
【Flutter×鸿蒙】debug 包也要签名,这点和 Android 差远了
android·flutter·harmonyos
Kapaseker2 小时前
2026年,我们还该不该学编程?
android·kotlin
雨白18 小时前
Android 快捷方式实战指南:静态、动态与固定快捷方式详解
android
hqk18 小时前
鸿蒙项目实战:手把手带你实现 WanAndroid 布局与交互
android·前端·harmonyos
LING19 小时前
RN容器启动优化实践
android·react native
恋猫de小郭21 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker1 天前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴1 天前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭2 天前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter