1.介绍
我们使用kotlin
的时候,会经常用到一些如let、apply、run
这些作用域函数,它能让我们方便、简洁地链式调用对象的方法,除了这些,Kotlin标准库还提供了 takeIf
函数和 takeUnless
函数. 这些函数允许你在链式调用中加入对象的状态检查。
2.使用场景
我们在写if语句的时候经常会遇到这样的场景:前面调用了一个函数计算得出了一个结果,现在需要对这个结果做一个分支判断,并且我们只需要用到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
}
- 是扩展函数
- 上下文对象的引用方式:it
- 返回值:如果代码块predicate里面返回为true,则返回这个对象本身,否则返回空
- 使用注意:结果要用?判空
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
}
- 是扩展函数
- 上下文对象的引用方式:it
- 返回值:如果代码块predicate里面返回为false,则返回这个对象本身,否则返回空
- 使用注意:结果要用?判空
说明
从上面的用法可见它们之间的区别就只有一个是满足代码块里面的条件才返回对象本身,一个是不满足条件才返回,如例子用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
优点
- 可以配合其他作用域函数返回的结果,做出单向判断,保持链式调用
- 简化写法,逻辑清晰,减少代码量,代码更优雅。
如果需要两个分支?
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")
}
网友评论