当前位置: 首页 > news >正文

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)

结束。


http://www.mrgr.cn/news/11057.html

相关文章:

  • tekton什么情况下在Dockerfile中需要用copy
  • JMeter之插件jp@gc - Stepping Thread Group
  • 数字芯片设计验证经验分享(第三部分):将ASIC IP核移植到FPGA上——如何确保性能与时序以完成充满挑战的任务!
  • C语言典型例题52
  • Midjourney推出网页版编辑器应对Ideogram 2.0冲击
  • 目标小程序和当前小程序主体必须为绑定在同一0pen下的相关或关联主体
  • 大数据技术之Flume事务及内部原理(3)
  • 6U VPX总线架构:搭载飞腾D2000/FT2000 + FPGA-K7(赛灵思)
  • 如何自己通过java实现一个rpc框架?简单例子
  • docker基本环境搭建
  • 谷粒商城篇章11--P311-P325--秒杀服务【分布式高级篇八】
  • 从etcd学习raft
  • 移动式气象站:科技赋能,监测天气
  • sheng的学习笔记-AI-半监督SVM
  • 远程线程注入--DLL注入(C++)
  • springboot集成quartz实现配置化定时任务
  • C++学习笔记----5、重用之设计(二)---- 为最优化重用结构化你的代码(1)
  • 微信小程序主体变更(迁移)法人无法配合扫脸怎么办?
  • 如何定义、注册以及什么是异步组件?
  • 使用xinference部署自定义embedding模型(docker)