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

引言

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

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

查了资料看看概念:

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

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

 共有以下五种:letrunwithapply以及also。 

结论:

函数对象引用返回值是否是扩展函数
letitLambda表达式结果
runthisLambda表达式结果
run-Lambda表达式结果不是:调用无需上下文对象
withthisLambda表达式结果不是:把上下文对象当做参数
applythis上下文对象
alsoit上下文对象

用法:

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

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

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

also

函数声明

public inline fun <T> T.also(block: (T) -> Unit): T

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

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

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

例子:

val alsoResult = book.also {
    it.changePrice(20)
    it.name = "alsoResult"
}
println("alsoResult $alsoResult")

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

apply

函数声明

public inline fun <T> T.apply(block: T.() -> Unit): T

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

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

val applyResult = book.apply {
    changePrice(200)
    name = "applyResult"
}
println("applyResult $applyResult")

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

let

函数声明

public inline fun <T, R> T.let(block: (T) -> R): R

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

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

run

函数声明

public inline fun <T, R> T.run(block: T.() -> R): R
public inline fun <R> run(block: () -> R): R

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

with

函数声明

public inline fun <T, R> with(receiver: T, block: T.() -> R): R

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

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

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

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

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

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

结束。

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值