常见标准函数with,run,apply,let

  • 前言
  • 标准函数
  • with函数
  • run函数
  • apply函数
  • let函数


抓住今天,尽可能少的信赖明天。 喝汤能补 (* ^ ▽ ^ *)

前言

  该文章作为学习交流,如有错误欢迎各位大佬指正 (* ^ ▽ ^ *)

  • 自身技能
    (1)已具备计算机的基本知识
    (2)了解Lambda语法
  • 本文简介
    主要讲解:关于标准函数库中with,run,apply,let函数的用法。

标准函数

    Kotlin的标准函数指的是Standard.kt文件中定义的函数,任何Kotlin代码都可以自由地调用所有的标准函数。

小结

  • 表达式中提供第一个参数对象的上下文:简单理解,在该表达式中,可以像在参数对象的类中一样,直接调用类中的方法,不需要使用 对象.funxx() 的方式进行调用。
  • with,run,apply这几个函数的用法非常类似,但我们要能知道他们的差异,并在编程中选择最佳的函数。

with与run与apply

区别

参数

是否可直接调用

是否能以Lambda表达式作为返回值

with

两个参数

任意对象,Lambda表达式



run

一个参数

Lambda表达式


需对象调用


run

一个参数

Lambda表达式


需对象调用


返回调用对象本身

with函数

   with函数接收两个参数:第一个参数可以是任意类型的对象,第二个参数是一个Lambda表达式。with函数会在Lambda表达式中提供第一个参数对象的上下文, 且使用Lambda表达式中最后一行代码作为返回值返回。

// 基本语法
    val result = with(obj){
        // 这里是obj的上下文
        "value" //with函数的返回值
    }

简单示例

val list = listOf("A", "B", "C", "D", "E", "F")
    val result = with(StringBuilder()) {
        append(" Connect them together \n")
        for (word in list) {
            append(word).append(" ")
        }
        append(" no word  ")
    }
    println(result)

run函数

   run函数用法与with函数类似,语法上有点差异。无法直接调用run函数,必须某个对象调用run函数才行;run函数只接受一个Lambda参数,也会在Lambda表达式中提供调用对象的上下文, 以及使用Lambda表达式中最后一行代码作为返回值返回。

// 基本语法
    val result = obj.run(){
        // 这里是obj的上下文
        "value" //with函数的返回值
    }

简单示例

val list = listOf("A", "B", "C", "D", "E", "F")
    val result = StringBuilder().run() {
        append(" Connect them together \n")
        for (word in list) {
            append(word).append(" ")
        }
        append(" no word  ")
    }
    println(result)

apply函数

   apply函数与run函数类似,必须某个对象调用apply函数;apply函数只接受一个Lambda参数,也会在Lambda表达式中提供调用对象的上下文。
   差异点在于:apply函数无法指定返回值,而是自动返回调用对象本身。

// 基本语法
    val result = obj.apply(){
        // 这里是obj的上下文
    }
    // return == obj

简单示例

val list = listOf("A", "B", "C", "D", "E", "F")
    val result = StringBuilder().apply() {
        append(" Connect them together \n")
        for (word in list) {
            append(word).append(" ")
        }
        append(" no word  ")
    }
    println(result.toString())

let函数

这个函数将原始调用对象作为参数传递到Lambda表达式中。
  将obj对象传递到lambda表达式中,参数名为obj2,但obj与obj2 是同一个对象。

  • let可以用来处理全局变量为空判断,而if则不行,因为无法保证if语句中的全局变量不被其他线程所修改。
val obj=""
    obj.let {
        obj2 ->
        //编写具体的业务
    }

使用let与?.更加简化为空判断

fun useFun1(an: Animal?){
    an?.eat()
    an?.say()
}

// 优化
fun useFun2(an: Animal?){
    an?.let { 
        a ->
        a.say()
        a.eat()
    }
}

// 上篇说的,只有一个参数,可以使用it
    an?.let {
        it.say()
        it.eat()
    }
// 无法编译通过

var animal :Animal? = null

fun useFun3(an: Animal?){
    if (animal != null){
        animal.say() //还是报错,animal可能被其他线程修改成null
        animal.eat()
    }
}