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")
}