解析Kotlin:let ,apply,run,with,also,takeif

let

定義:默認當前這個對象作爲閉包的it參數,返回值是函數裏面最後一行,或者指定return

源碼

/**
 * Calls the specified function [block] with `this` value as its argument and returns its result.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#let).
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

使用: 判斷對象是否爲空,使代碼看起來更加優美

package `fun`

class test {

    var count: Int = 0

    fun funtion() {
        println("run funtion $count")
        count++
    }
}

fun main(args:Array<String>) {
    // 不使用 let 判空
    val tmp = test()
    if (tmp != null) {
        tmp?.funtion()
        tmp?.funtion()
        tmp?.funtion()
    }

    // 使用let
    tmp.let {
        it.funtion()
        it.funtion()
        it.funtion()
    }
}

also

類似let函數,但區別在於返回值:

let函數:返回值 = 最後一行 / return的表達式
also函數:返回值 = 傳入的對象的本身

源碼


/**
 * Calls the specified function [block] with `this` value as its argument and returns `this` value.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#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
}
  • 使用
package `fun`

class also_test {

    var count: Int = 0

    fun funtion() {
        println("run also funtion $count")
        count++
    }
}

fun main(args:Array<String>) {
    val tmp = also_test()

    // 使用let
    val result_let = tmp.let {
        it.funtion()
        it.funtion()
        it.funtion()
        "hello let"
    }
    println(result_let)
    // 使用also
    val result_also = tmp.also {
        it.funtion()
        it.funtion()
        it.funtion()
        "hello also"
    }
    println(result_also)
}

輸出
在這裏插入圖片描述

apply

與run函數類似,但區別在於返回值:

run函數返回最後一行的值 / 表達式

T.() : 代表自身的對象來調用它
(T) : 某一個對象的調用

源碼


/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#apply).
 */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

使用

// 改寫apply函數
public inline fun <T> T.apply1(block: T.() -> Unit): T {
    return this
}

public inline fun <T> T.apply2(block: (T) -> Unit): T {
   return this
}


anyObject.apply1 {  // this: MutableList<String>
    add("addObject")
}

anyObject.apply2 {  // it: MutableList<String>
    it.add("addObject")
}

with

調用同一個對象的多個方法 / 屬性時,可以省去對象名重複,直接調用方法名 / 屬性即可

源碼


/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#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(object){
   // ... 
 }

// 返回值 = 函數塊的最後一行 / return表達式

run

結合了let、with兩個函數的作用,即:

調用同一個對象的多個方法 / 屬性時,可以省去對象名重複,直接調用方法名 / 屬性即可
定義一個變量在特定作用域內
統一做判空處理

源碼

/**
 * Calls the specified function [block] and returns its result.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#run).
 */
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

使用:

object.run{
// ... 
}
// 返回值 = 函數塊的最後一行 / return表達式

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
}

從源碼可以看出來:它是從T對象本身調用的。即T.takeIf,
predicate函數以T對象爲參數
等待predicate評估後它返回this或null

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章