[kotlin基础] let、run、with、apply、also 函数区别

119 阅读1分钟

前言

在使用kotlin的过程中,经常会操作对象,例如对象非空逻辑对象属性初始化等。 几个官方针对不同的场景,提供一些函数,供我们使用,但是这么多,如何使用,对于新手同学,可能会是一个问题。
本文根据使用场景对他们做一个分类:

  1. 函数的返回值:run(),let()also(),apply()
  2. 函数参数:run(),apply()also(),let()
根据返回值区分 run(),let()also(),apply()

主要分为两组,一组是返回当前函数的对象,另外一组返回最后一行的对象。

//eg: Person类
data class Person(val name: String, var age: Int, var money: Int?) {
    fun work() {
        println("Person is working ")
    }
    override fun hashCode(): Int {
        return super.hashCode()
    }
}
//eg: 学生类
data class Student(var person: Person)

当前函数的对象 also(),apply()

val alsoTom = tom.also {
    it.age = 20
    Student(it)
}
val applyTom = tom.apply {
    age = 20
    Student(this)
}

println("tom person info ${alsoTom === tom}")   //true
println("tom person info ${applyTom === tom}")  //true

返回最后一行的对象run(),let()

val letTom = tom.let {
    it.age = 20
    Student(it)
}
val runTom = tom.run {
    age = 20
    Student(this)
}
println("tom person info ${letTom.person === tom}")  //true
println("tom person info ${runTom.person === tom}")  //true

其实原因就在于内联函数的返回值,前面一种是 return this ,后面一种是return block(this)

根据参数区分 run(),apply()also(),let()

根据返回值区分时,我们发现 also(),apply()效果一样,那他们的区别在于哪里呢?

val alsoTom = tom.also { person ->
    person.age = 20
}
val applyTom = tom.apply {
    age = 20
}

把高阶函数的参数放开后发现,also 是把当前对象 传入进去,而apply 是当前函数的扩展函数
also 入参: block: (T) -> Unit
apply 入参: block: T.() -> Unit

with()

with() 入参和返回值和 run()相似,本质区别在于,他们一个是 扩展函数,一个是普通函数