Kotlin(十一) 标准函数with、run和apply

with

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

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

那么这个函数有什么作用呢?它可以在连续调用同一个对象的多个方法时让代码变得更加精简,下面我们来看一个具体的例子。

比如有一个水果列表,现在我们想吃完所有水果,并将结果打印出来,就可以这样写:

    val  list = listOf("苹果","香蕉","梨","火龙果","芭蕉","椰子")
    val  builder = StringBuilder()
    builder.append("开始\n")
    for (fruit in list){
        builder.append(fruit).append("\n")
    }
    builder.append("结束\n")
    println(builder.toString())

仔细观察上述代码,你会发现我们连续调用了很多次builder对象的方法。其实这个时候就可以考虑使用with函数来让代码变得更加精简,如下所示:

    val builderWith = with(StringBuilder()) {
        append("开始\n")
        for (fruit in list) {
            append(fruit).append("\n")
        }
        append("结束").append("\n")
        toString()
    }
    println(builderWith)

这两段代码的执行结果是一模一样的,但是明显第二段代码的写法更加简洁一些,这就是with函数的作用。

run

run函数的用法和使用场景其实和with函数是非常类似的,只是稍微做了一些语法改动而已。首先run函数通常不会直接调用,而是要在某个对象的基础上调用;其次run函数只接收一个Lambda参数,并且会在Lambda表达式中提供调用对象的上下文。其他方面和with函数是一样的,包括也会使用Lambda表达式中的最后一行代码作为返回值返回。示例代码如下:

val result = obj.run {
    // 这里是obj的上下文
    "value" // run函数的返回值
}

那么现在我们就可以使用run函数来修改一下吃水果的这段代码,如下所示:

    val builderRun = StringBuilder().run {
        append("开始\n")
        for (fruit in list) {
            append(fruit).append("\n")
        }
        append("结束").append("\n")
        toString()
    }
    println(builderRun)

总体来说变化非常小,只是将调用with函数并传入StringBuilder对象改成了调用StringBuilder对象的run方法,其他都没有任何区别,这两段代码最终的执行结果是完全相同的。

apply

apply函数和run函数也是极其类似的,都要在某个对象上调用,并且只接收一个Lambda参数,也会在Lambda表达式中提供调用对象的上下文,但是apply函数无法指定返回值,而是会自动返回调用对象本身。示例代码如下:

val result = obj.apply {
     // 这里是obj的上下文
}
// result == obj

那么现在我们再使用apply函数来修改一下吃水果的这段代码,如下所示:

    val builderApply = StringBuilder().apply {
        append("开始\n")
        for (fruit in list) {
            append(fruit).append("\n")
        }
        append("结束").append("\n")
    }
    println(builderApply.toString())

注意这里的代码变化,由于apply函数无法指定返回值,只能返回调用对象本身,因此这里的result实际上是一个StringBuilder对象,所以我们在最后打印的时候还要再调用它的toString()方法才行。

你可能感兴趣的:(Kotlin学习之路,kotlin,开发语言,android)