Kotlin里的takeIf和takeUnless

1.介紹

我們使用kotlin的時候,會經(jīng)常用到一些如let、apply、run這些作用域函數(shù),它能讓我們方便、簡潔地鏈式調(diào)用對象的方法,除了這些,Kotlin標準庫還提供了 takeIf 函數(shù)和 takeUnless 函數(shù). 這些函數(shù)允許你在鏈式調(diào)用中加入對象的狀態(tài)檢查。

2.使用場景

我們在寫if語句的時候經(jīng)常會遇到這樣的場景:前面調(diào)用了一個函數(shù)計算得出了一個結(jié)果,現(xiàn)在需要對這個結(jié)果做一個分支判斷,并且我們只需要用到if的一個分支時,可以用takeIf和takeUnless代替

    fun testWithoutTakeIf() {
        val name = "maozonghong"
        val hasMao = name.indexOf("mao")
        Log.i(TAG, "testWithoutTakeIf: hasMao = $hasMao")
        if (hasYan >= 0) {
            Log.i(TAG, "testWithoutTakeIf: has mao")
        }
        Log.i(TAG, "testWithoutTakeIf: $name")
    }
    
輸出:
I: testWithoutTakeIf: hasMao = 0
I: testWithoutTakeIf: has mao
I: testWithoutTakeIf: maozonghong

可以寫成:

    fun testTakeIf() {
        val name = "maozonghong"
        name.indexOf("mao")
            .takeIf {
                Log.i(TAG, "testTakeIf: it = $it")
                it >= 0
            }
            ?.let {
                Log.i(TAG, "testTakeIf: has mao")
            }
        Log.i(TAG, "testTakeIf: $name")
    }
   
輸出:
I: testTakeIf: it = 0
I: testTakeIf: has mao
I: testTakeIf: maozonghong

用法

1. takeif

public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (predicate(this)) this else null
}
  • 是擴展函數(shù)
  • 上下文對象的引用方式:it
  • 返回值:如果代碼塊predicate里面返回為true,則返回這個對象本身,否則返回空
  • 使用注意:結(jié)果要用?判空

2.takeUnless

public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (!predicate(this)) this else null
}
  • 是擴展函數(shù)
  • 上下文對象的引用方式:it
  • 返回值:如果代碼塊predicate里面返回為false,則返回這個對象本身,否則返回空
  • 使用注意:結(jié)果要用?判空

說明

從上面的用法可見它們之間的區(qū)別就只有一個是滿足代碼塊里面的條件才返回對象本身,一個是不滿足條件才返回,如例子用takeUnless寫可以寫成:

    fun testTakeUnless() {
        val name = "maozonghong"
        name.indexOf("mao")
            .takeUnless {
                Log.i(TAG, "testTakeUnless: it = $it")
                it < 0
            }
            ?.let {
                Log.i(TAG, "testTakeUnless: has mao")
            }
        Log.i(TAG, "testTakeUnless: $name")
    }
    
輸出:
I: testTakeUnless: it = 0
I: testTakeUnless: has  mao
I: testTakeUnless: maozonghong

優(yōu)點

  • 可以配合其他作用域函數(shù)返回的結(jié)果,做出單向判斷,保持鏈式調(diào)用
  • 簡化寫法,邏輯清晰,減少代碼量,代碼更優(yōu)雅。

如果需要兩個分支?

name.indexOf("mao")
            .takeIf {
                Log.i(TAG, "testTakeIf: it = $it")
                it >= 0
            }
            ?.let {
                Log.i(TAG, "testTakeIf: has mao")
            }?: run{
Log.i(TAG, "testTakeIf: no mao")
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容