kotlin

Kotlin里的takeIf和takeUnless

2022-05-07  本文已影响0人  竖起大拇指

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
}

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
}

说明

从上面的用法可见它们之间的区别就只有一个是满足代码块里面的条件才返回对象本身,一个是不满足条件才返回,如例子用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")
}
上一篇 下一篇

猜你喜欢

热点阅读