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

一、概述

为了帮助您根据使用场景选择合适的作用域函数(scope function),我们将对它们进行详细描述并提供使用建议。从技术上讲,许多情况下范围函数是可以互换使用的,因此示例中展示了使用它们的约定俗成的做法。

1.let函数

  • 上下文对象作为参数(it)提供。

  • 返回值:lambda表达式结果.

let可以用于在调用链的结果上调用一个或多个函数。例如:

Kotlin 复制代码
var name = "kotlin"
var sub = name.substring(0,2)
println(sub)

用let重写上面的例子,不用分配一个新的变量就会直接输出结果:

Kotlin 复制代码
var name = "kotlin"
name.substring(0,2).let {
    println(it)
}

let代码块里,如果只有一个函数,且函数只有一个参数it,可以用::代替it参数:

Kotlin 复制代码
var name = "kotlin"
name.substring(0,2).let(::println)

let代码块里操作的数值为非空值,为了操作非空数值,需要在let前用 ?.操作符

Kotlin 复制代码
val name: String? = null
name?.let {
      println(it)
}

为了让代码更用阅读可以自定义变量,代替it参数:

Kotlin 复制代码
val name: String = "kotlin"
val child: String? = name.substring(0, 2)
child?.let { sub ->
    println(sub)//sub为自定义的变量代替it参数
}

2.with函数

  • 上下文对象作为接收者(this)可用。

  • 返回值:lambda表达式结果.

with 不是一个扩展函数:上下文对象this作为参数传递,在lamda表达式里this可以被当作接收者.

当不需要返回结果时,推荐用with时,可以引用上下文对象调用方法。例如,

Kotlin 复制代码
val name = "kotlin"
with(name){
  println(this)
}

可以在lamda代码块里,引用上下文对象的属性和函数,例如,

Kotlin 复制代码
val name = "kotlin"
println(
 "result:${
     with(name) {
        length + substring(0, 2).length
     }
 }"
)

3.run函数

  • 上下文对象作为接收者(this)可用。

  • 返回值:lamda表达式结果

run 跟with作用相同,但run是一个扩展函数。像let,对象可以通过点符号引用run。当lamada表达式中同时有初始化和计算操作,可用run函数。例如,

Kotlin 复制代码
class User{
            var name: String? = null
            var age = 0
        }

        User().run {
            name = "java"
            age = 99
            Log.d(TAG,"User:$name,$age")
        }

你还可以将 run 作为非扩展函数来调用。run 的非扩展版本没有上下文对象,但它仍然返回 lambda 表达式的结果。非扩展的 run 允许你在需要表达式的地方执行多个语句的代码块 。在代码中,非扩展的 run 可以理解为"运行代码块并计算结果"。例如,

Kotlin 复制代码
 var name = "c++"
 name.run {
      var y = "123"
      println("$this,$y")
 }

4.apply函数

  • 上下文对象作为接收者(this)可用。

  • 返回值:this对象本身.

因为 apply 函数返回引用对象本身,主要用于对象的成员操作时,可用apply函数。主要应用appply函数的地方是对象的配置。对apply调用可以被当作是对象的初始化。

Kotlin 复制代码
class User {
            var name: String? = null
            var age = 0
            fun set(ageParam: Int) {
                age = ageParam
            }

            fun get(): Int {
                return age
            }
        }

        User().apply {
            name = "java"
            age = 99
            set(100)
            Log.d(TAG, "User:$name,${get()}")
        }

另一个 apply 的使用场景是将其包含在多个调用链中,以进行更复杂的处理。例如,

Kotlin 复制代码
class User {
            var name: String? = null
            var age = 0
            fun set(ageParam: Int) {
                age = ageParam
            }

            fun get(): Int {
                return age
            }
        }

        User().apply {
            name = "java"
            age = 99
            set(100)
            Log.d(TAG, "User:$name,${get()}")
        }.apply {
            name = "c++"
            Log.d(TAG, "User:$name,${get()}")
        }

5.also函数

  • 上下文对象作为参数(it)提供.

  • 返回值:引用对象本身

also 用于操作上下文参数对象。引用also的操作都是针对引用对象(而不是它的属性和方法)或者是不想对外部作用域隐藏this对象。

常用于链式调用中,在不改变对象的情况下,插入一些中间操作。

当看到also时,可以读作"also跟随对象"。

Kotlin 复制代码
User().also {
            it.set(100)
            Log.d(TAG,"also引用,user:${it.age}")
        }.also {
            it.set(99)
            it.name = "kotlin"
        }.run {
            Log.d(TAG,"run引用,user:$name, $age")
        }

二、区别

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

相关推荐
yzpyzp6 小时前
如果后台的Long类型的数据返回是null,那么Android客户端的数据bean的kotlin的Long类型的字段接受到数据后是null空指针吗?
android·kotlin
xvch10 小时前
Kotlin 2.1.0 入门教程(二十五)类型擦除
android·kotlin
有点感觉2 天前
Android级联选择器,下拉菜单
kotlin
zhangphil2 天前
Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(1)
android·kotlin
xvch2 天前
Kotlin 2.1.0 入门教程(二十三)泛型、泛型约束、协变、逆变、不变
android·kotlin
xvch4 天前
Kotlin 2.1.0 入门教程(二十四)泛型、泛型约束、绝对非空类型、下划线运算符
android·kotlin
zhangphil4 天前
Android Coil ImageLoader MemoryCache设置Key与复用内存缓存,Kotlin
android·kotlin
mmsx4 天前
kotlin Java 使用ArrayList.add() ,set()前面所有值被 覆盖 的问题
android·开发语言·kotlin
lavins4 天前
android studio kotlin项目build时候提示错误 Unknown Kotlin JVM target: 21
jvm·kotlin·android studio
面向未来_5 天前
JAVA Kotlin Androd 使用String.format()格式化日期
java·开发语言·kotlin