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

相关推荐
Kapaseker9 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
FunnySaltyFish2 天前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Kapaseker2 天前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
Kapaseker3 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
A0微声z5 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin
alexhilton6 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
lhDream6 天前
Kotlin 开发者必看!JetBrains 开源 LLM 框架 Koog 快速上手指南(含示例)
kotlin
RdoZam6 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
Kapaseker6 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin