kotlin内联函数——let,run,apply,also,with的区别

农民  金牌会员 | 2025-1-25 04:29:34 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 871|帖子 871|积分 2613

一、概述

为了资助您根据使用场景选择合适的作用域函数(scope function),我们将对它们举行具体描述并提供使用发起。从技术上讲,许多情况下范围函数是可以交换使用的,因此示例中展示了使用它们的约定俗成的做法。
1.let函数



  • 上下文对象作为参数(it)提供。
  • 返回值:lambda表达式结果.
let可以用于在调用链的结果上调用一个或多个函数。例如:
  1. var name = "kotlin"
  2. var sub = name.substring(0,2)
  3. println(sub)
复制代码
用let重写上面的例子,不消分配一个新的变量就会直接输出结果:
  1. var name = "kotlin"
  2. name.substring(0,2).let {
  3.     println(it)
  4. }
复制代码
let代码块里,假如只有一个函数,且函数只有一个参数it,可以用::取代it参数:
  1. var name = "kotlin"
  2. name.substring(0,2).let(::println)
复制代码
let代码块里操作的数值为非空值,为了操作非空数值,需要在let前用?.操作符:
  1. val name: String? = null
  2. name?.let {
  3.       println(it)
  4. }
复制代码
为了让代码更用阅读可以自定义变量,取代it参数:
  1. val name: String = "kotlin"
  2. val child: String? = name.substring(0, 2)
  3. child?.let { sub ->
  4.     println(sub)//sub为自定义的变量代替it参数
  5. }
复制代码
2.with函数



  • 上下文对象作为吸取者(this)可用。
  • 返回值:lambda表达式结果.
 with 不是一个扩展函数:上下文对象this作为参数传递,在lamda表达式里this可以被当作吸取者.
当不需要返回结果时,推荐用with时,可以引用上下文对象调用方法。例如,
  1. val name = "kotlin"
  2. with(name){
  3.   println(this)
  4. }
复制代码
可以在lamda代码块里,引用上下文对象的属性和函数,例如,
  1. val name = "kotlin"
  2. println(
  3. "result:${
  4.      with(name) {
  5.         length + substring(0, 2).length
  6.      }
  7. }"
  8. )
复制代码
3.run函数



  • 上下文对象作为吸取者(this)可用。
  • 返回值:lamda表达式结果
run 跟with作用类似,但run是一个扩展函数。像let,对象可以通过点符号引用run。当lamada表达式中同时有初始化和盘算操作,可用run函数。例如,
  1. class User{
  2.             var name: String? = null
  3.             var age = 0
  4.         }
  5.         User().run {
  6.             name = "java"
  7.             age = 99
  8.             Log.d(TAG,"User:$name,$age")
  9.         }
复制代码
你还可以将 run 作为非扩展函数来调用。run 的非扩展版本没有上下文对象,但它仍然返回 lambda 表达式的结果。非扩展的 run 允许你在需要表达式的地方执行多个语句的代码块。在代码中,非扩展的 run 可以理解为“运行代码块并盘算结果”。例如,
  1. var name = "c++"
  2. name.run {
  3.       var y = "123"
  4.       println("$this,$y")
  5. }
复制代码
4.apply函数



  • 上下文对象作为吸取者(this)可用。
  • 返回值:this对象自己.
因为 apply 函数返回引用对象自己,主要用于对象的成员操作时,可用apply函数。主要应用appply函数的地方是对象的配置。对apply调用可以被当作是对象的初始化。
  1. class User {
  2.             var name: String? = null
  3.             var age = 0
  4.             fun set(ageParam: Int) {
  5.                 age = ageParam
  6.             }
  7.             fun get(): Int {
  8.                 return age
  9.             }
  10.         }
  11.         User().apply {
  12.             name = "java"
  13.             age = 99
  14.             set(100)
  15.             Log.d(TAG, "User:$name,${get()}")
  16.         }
复制代码
另一个 apply 的使用场景是将其包含在多个调用链中,以举行更复杂的处理处罚。例如,
  1. class User {
  2.             var name: String? = null
  3.             var age = 0
  4.             fun set(ageParam: Int) {
  5.                 age = ageParam
  6.             }
  7.             fun get(): Int {
  8.                 return age
  9.             }
  10.         }
  11.         User().apply {
  12.             name = "java"
  13.             age = 99
  14.             set(100)
  15.             Log.d(TAG, "User:$name,${get()}")
  16.         }.apply {            name = "c++"            Log.d(TAG, "User:$name,${get()}")        }
复制代码
5.also函数



  • 上下文对象作为参数(it)提供.
  • 返回值:引用对象自己
also 用于操作上下文参数对象。引用also的操作都是针对引用对象(而不是它的属性和方法)或者是不想对外部作用域隐藏this对象。
常用于链式调用中,在不改变对象的情况下,插入一些中间操作。
当看到also时,可以读作“also跟随对象”。
  1. User().also {
  2.             it.set(100)
  3.             Log.d(TAG,"also引用,user:${it.age}")
  4.         }.also {
  5.             it.set(99)
  6.             it.name = "kotlin"
  7.         }.run {
  8.             Log.d(TAG,"run引用,user:$name, $age")
  9.         }
复制代码
二、区别

1.参数

自定义参数it名字:唯独let函数可以自定义参数it名字
函数参数传递:唯独with函数把引用对象作为参数输入例如,with(name){}
2.返回值

let,with和run返回值为lamda表达式结果,而apply和also返回值为引用对象自己
3.参数this和it

参数为this的函数为with,run和apply,可直接操作对象的属性和方法。
参数为it的函数为不能直接操作对象的属性和方法。










推荐文章
Scope functions | Kotlin Documentation

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农民

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表