Kotlin标准函数

Kotlin标准函数

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

let函数

let这个标准函数,主要作用是配合?.操作符来进行辅助判空操作。obj?.let(o -> //xxxx)

这个函数提供了函数式API的编程接口,并将原始调用对象作为参数传递到Lambda表达式中。

obj.let { obj2 ->
    //编写具体的业务逻辑
}

这里调用了obj对象的let函数,然后Lambda表达式中的代码就会立即执行,并且这个obj对象本身还会作为参数传递到Lambda表达式中。不过为了防止变量重名,这里将参数名改为了obj2,但实际上它们是同一个对象,这就是let函数的作用。

这样看起来let函数并没有什么意义。

但是有这样一种场景:

fun doStudy(study: Study?) {
    study?.readBooks()
    study?.doHomework()
}

这段代码可以编译通过,运行也正常。但是实际上,这段代码翻译后,是类似于下面这样的代码:

fun doStudy(study: Study?) {
    if(study != null) {
        study.readBooks()
    }
    if(study != null) {
        study.doHomework()
    }
}

可以看到,有对study对象是否为null的重复判断。

但如果使用let函数配合?,如下所示:

fun doStudy(study: Study?) {
    study?.let { stu ->
        stu.readBooks()
        stu.doHomework()
    }
}

这段代码翻译后,是类似于下面这样的代码:

fun doStudy(study: Study?) {
    if(study != null) {
        study?.readBooks()
        study?.doHomework()
    }
}

with函数

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

示例代码:

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

with函数的作用:他可以在连续迪奥用同一个对象的多个方法时,让代码变得更加精简。

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

val list = listOf{"Apple", "Banana", "Orange", "Pear", "Grape"}
val builder = StringBuilder()
builder.append("Start eating fruits.\n")
for(fruit in list) {
    builder.append(fruit).append("\n")
}
builder.append("Ate all fruits.")
val result = builder.toString()
println(result)

如果使用with函数,代码可以变得更加精简

val list = listOf{"Apple", "Banana", "Orange", "Pear", "Grape"}
val result = with(StringBuilder()) {
    append("Start eating fruits.\n")
    for(fruit in list) {
        append(fruit).append("\n")
    }
    append("Ate all fruits.")
    toString()
}
println(result)

run函数

run函数的用法和使用场景其实和with函数是非常类似的,只是稍微做了一下语法改动而已。

首先run函数通常不会直接调用,而是要在某个对象的基础上调用; 其次run函数只接受一个Lambda参数,并且会在Lambda表达式中提供调用对象的上下文。

其他方面和with函数是一样的,包括也会使用Lambda表达式中的最后一行代码作为返回值返回。

示例代码:

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

eg:使用run标准函数实现前面吃水果的代码:

val list = listOf{"Apple", "Banana", "Orange", "Pear", "Grape"}
val result = StringBuilder().run {
    append("Start eating fruits.\n")
    for(fruit in list) {
        append(fruit).append("\n")
    }
    append("Ate all fruits.")
    toString()
}
println(result)

apply函数

apply标准函数和run函数也是极其类似的。

都要在某个对象上调用,并且只接受一个Lambda参数,也会在Lambda表达式中提供调用对象的上下文。

但是apply函数无法指定返回值,而是返回调用对象本身。

示例代码:

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

eg:使用apply函数实现前面吃水果的代码:

val list = listOf{"Apple", "Banana", "Orange", "Pear", "Grape"}
val result = StringBuilder.apply {
    append("Start eating fruits.\n")
    for(fruit in list) {
        append(fruit).append("\n")
    }
    append("Ate all fruits.")
}
println(result.toString())

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

实际上with, run, apply这几个函数的用法和使用场景是非常类似的。在大多数情况下,它们可以互相转换。


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注