Kotlin标准库中常用扩展函数总结

Kotlin标准库中有一些非常实用的扩展函数。

  • run
/**
 * Calls the specified function [block] with `this` value as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

run是任何类型T的通用扩展函数,run中执行了返回类型为R的扩展函数block,最终返回该扩展函数的结果。

在run函数中我们拥有一个单独的作用域,能够重新定义一个新变量,并且它的作用域只存在于run函数中。

fun testPayFoo() {
    val nickName = "Perfect"

    run {
        val nickName = "PAYZY"
        println(nickName)
    }

    println(nickName)
}

fun main() {
    testPayFoo()
}

PAYZY
Perfect

并且它返回范围内最后一个对象。

例子:

data class StuA(val name: String)

fun testPayFoo2() {
    val run = run {
        println("test return")
        StuA("PAYZY")
    }
    println(run)
}

fun main() {
    testPayFoo2()
}

test return
StuA(name=PAYZY)
  • let
/**
 * Calls the specified function [block] with `this` value as its argument and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

let与apply类似,唯一不同的是返回值:apply返回的是原来的对象,而let返回的是闭包里面的值。let同样限制了变量的作用域。

data class Student(val age: Int)
class PayKot {
    val stu: Student? = Student(2)
    fun dealStu() {
        val result = stu?.let {
            println(it.age)
            it.age
        }
        println("result:$result")
    }
}


fun main() {
    PayKot().dealStu()
}

2
result:2
  • also

also是Kotlin1.1版本中新加入的内容,它像是let和apply函数的加强版。

/**
 * Calls the specified function [block] with `this` value as its argument and returns `this` value.
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block(this)
    return this
}

与apply一致,它的返回值是该函数的接收者。

data class PayStudent(val age: Int)
class PayZKot {
    val student: PayStudent? = PayStudent(666)
    var age = 0
    fun dealStu() {
        val result = student?.also { stu ->
            this.age += stu.age
            println(this.age)
            println(stu.age)
            this.age
        }
        println("result:$result")
    }
}

fun main() {
    PayZKot().dealStu()
}

666
666
result:PayStudent(age=666)

在上面代码中,将其隐式参数指定为stu,假设 student?不为空,会返回student,并且总年龄 this.age增加了。

主要注意的是:如果使用apply,由于其内部是一个扩展函数,this将指向stu而不是PayZKot,此时就无法调用到PayKot下的age。

  • takeIf

如果不仅仅想判空,还要加入条件,这时let就有些不足。这时可以使用takeIf 。

/**
 * Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (predicate(this)) this else null
}

这个函数也是在Kotlin1.1中新增加的。当接收器满足某些条件时才会执行。

例子:

class PayTestTakeIf {
    val stuA: PayStudent2? = PayStudent2(55)
    val stuB: PayStudent2? = PayStudent2(5)

    fun dealStu() {
        val let = stuA?.takeIf { it.age > 10 }?.let {
            println(it.age)
            it.age
        }
        println("let:$let")

        val takeIf = stuB?.takeIf { it.age > 10 }
        println(takeIf)
    }
}

fun main() {
    PayTestTakeIf().dealStu()
}

55
let:55
null

 参考Kotlin核心编程

 

 

 

 

发布了182 篇原创文章 · 获赞 179 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/zhangying1994/article/details/104875942