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)

结束。

相关推荐
gopyer12 小时前
180课时吃透Go语言游戏后端开发6:Go语言的循环语句
开发语言·游戏·golang·循环语句
楼田莉子15 小时前
Qt开发学习——QtCreator深度介绍/程序运行/开发规范/对象树
开发语言·前端·c++·qt·学习
Pika15 小时前
深入浅出 Compose 测量机制
android·android jetpack·composer
韩立学长15 小时前
【开题答辩实录分享】以《基于python的奶茶店分布数据分析与可视化》为例进行答辩实录分享
开发语言·python·数据分析
天若有情67316 小时前
C++空值初始化利器:empty.h使用指南
开发语言·c++
远远远远子16 小时前
类与对象 --1
开发语言·c++·算法
无敌最俊朗@16 小时前
C/C++ 关键关键字面试指南 (const, static, volatile, explicit)
c语言·开发语言·c++·面试
2401_8315017316 小时前
Python学习之day03学习(文件和异常)
开发语言·python·学习
酷~16 小时前
C语言模拟面向对象编程方法之多态
c语言·开发语言
hui函数17 小时前
python全栈(基础篇)——day03:后端内容(字符串格式化+简单数据类型转换+进制的转换+运算符+实战演示+每日一题)
开发语言·后端·python·全栈