阅读 100

Kotlin 中的特殊函数

run() 函数

run() 函数的定义如下:

@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}
复制代码

我们重点看最后一行代码 block(),其实就是调用传入的 block 参数,一般情况下是一个 Lambda 代码块。测试代码示例如下:

fun myFun(): String {
    println("执行了 myFun 函数")
    return "这是 myFun 的返回值"
}

fun main() {

    myFun() //直接在代码行调用函数

    run({ myFun() }) // 使用 run() 函数调用 myFun 函数

    run { myFun() } // run() 函数的括号 "()" 可以省略

    run { println("A") } //等价于 println("A")
}
复制代码

apply() 函数

apply() 函数的定义如下:

@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}
复制代码

同样,我们重点看最后两行代码,先是调用了 block() 函数,然后返回当前的调用者对象 this。意思是执行完 block() 代码块逻辑后,再次返回当前的调用者对象。测试代码示例如下:

fun testApply() {
    // 普通写法
    val list = mutableListOf<String>()
    list.add("A")
    list.add("B")
    list.add("C")
    println("普通写发 list = $list")

    // 使用 apply() 函数的写法
    val a = ArrayList<String>().apply {
        add("A")
        add("B")
        add("C")
        println("使用 apply 函数写法 this + $this")
    }

    println(a)

    //等价于
    a.let { println(it) }
}
复制代码

let() 函数

let() 函数的定义如下:

@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}
复制代码

同样,我们还是重点看最后一行代码 block(this),意思是把当前调用对象作为参数传入 block() 代码块中。测试代码示例如下:

fun myFun(): String {
    println("执行了 myFun 函数")
    return "这是 myFun 的返回值"
}

fun testLetFun() {
    "ABC".let {
        println(it)
    }

    myFun().let {
        //执行完 myFun,返回值传给 let() 函数
        println(it)
    }

}

fun main() {
    testLetFun()
}
// ABC
// 执行了 myFun 函数
// 这是 myFun 的返回值
复制代码

also() 函数

also() 函数的定义如下:

@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
}
复制代码

同样,我们还是看最后两句,首先是调用了 block(this),类似 let() 函数的逻辑,但是最后返回的值是 this,也就是当前的调用者。测试代码示例如下:

fun testAlsoFun(){
    val a = "ABC".also {
        println(it) //输出:ABC
    }

    println(a) //输出:ABC
    
    a.let { 
        println(it) //输出:ABC
    }
}
复制代码

with 函数

with 函数的定义如下:

@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}
复制代码

我们看到 with() 函数传入了一个接收者对象 receiver,然后使用该对象 receiver 去调用传入的 Lambda 代码块 receiver.block()。测试代码如下:

fun testWithFun() {
    // 普通写法
    val list = mutableListOf<String>()
    list.add("A")
    list.add("B")
    list.add("C")
    println("常规写法 list = $list")

    // 使用with() 函数写法
    with(ArrayList<String>()) {
        add("A")
        add("B")
        add("C")
        println("使用 with 函数写法 this = $this")
    }.let {
        println(it)
    }
}

fun main() {
    testWithFun()
}

// 常规写法 list = [A, B, C]
// 使用 with 函数写法 this = [A, B, C]
// kotlin.Unit
复制代码
文章分类
后端
文章标签