Kotlin内置函数之takeIf 和 takeUnless

498 阅读2分钟

Kotlin 中的 takeIftakeUnless 是标准库提供的两个作用域函数,用于简化条件判断和链式调用场景中的对象处理。以下是它们的核心特性和使用方式:

// takeIf 和 takeUnless 功能是相反的
// name.takeIf { true/false }  true:返回name本身,false返回null
// name.takeUnless { true/false }  false:返回name本身,true返回null

1. takeIf 函数

  • 定义‌:当对对象调用 takeIf 时,若其满足 Lambda 表达式中的条件(返回 true),则返回对象本身;否则返回 null‌12。

  • 用途‌:适用于对单个对象进行过滤或条件判断后继续操作。

  • 示例‌:

fun main() {
    val result = checkPermissionAction("Root2", "!@#$")
    // println("欢迎${result}尊贵的用户欢迎登录系统,拥有超级权限")
    if (result != null) {
        println("欢迎${result}尊贵的用户欢迎登录系统,拥有超级权限")
    } else {
        println("你的权限不够")
    }
    // name.takeIf { true/false }
    // true: 直接返回name本身
    // false: 直接放回null

    // 真正的用途
    println(checkPermissionAction2("Root", "!@#$"))

    // 小结:一般大部分情况下,都是 takeIf + 空合并操作符 = 一起使用
}

// 前端
public fun checkPermissionAction(name: String, pwd: String) : String? {
    return name.takeIf { permissionSystem(name, pwd) }
}

// takeIf + 空合并操作符
public fun checkPermissionAction2(name: String, pwd: String) : String {
    return name.takeIf { permissionSystem(name, pwd) } ?: "你的权限不够"
}

// 权限系统
private fun permissionSystem(username: String, userpwd: String) : Boolean {
    return if (username == "Root" && userpwd == "!@#$") true  else false
}



2. takeUnless 函数

  • 定义‌:与 takeIf 逻辑相反。当对象满足 Lambda 表达式中的条件(返回 true),则返回 null;否则返回对象本身‌12。

  • 用途‌:适合需要反向条件判断的场景。

  • 示例‌:

class Manager {
    private var infoValue: String? = null
    fun getInfoValue() /* : String? */ = infoValue
    fun setInfoValue(infoValue: String) {
        this.infoValue = infoValue
    }
}

fun main(){
   val manager = Manager()
//    manager.setInfoValue("AAA")
    // 小结:takeUnless+it.isNullOrBlank() 一起使用,可以验证字符串有没有初始化等功能
    var result = manager.getInfoValue().takeUnless { it.isNullOrBlank() }?: "未经过任何初始化值"
    println(result)
}

3. 核心区别

函数条件满足时返回值条件不满足时返回值
‌**takeIf**‌对象本身null
‌**takeUnless**‌null对象本身

4. 典型使用场景

  • 链式调用‌:简化多步操作中的条件判断,避免临时变量和嵌套 if 语句‌35。

    // 传统 if 语句 vs takeIf
    val result1 = if (user.age == 99) user.process() else null
    val result2 = user.takeIf { it.age == 99 }?.process() // 链式调用更简洁‌:ml-citation{ref="3,8" data="citationList"}
    
  • 空安全处理‌:结合安全调用操作符 ?. 处理可空对象‌46。

    user.takeIf { it.isValid() }?.saveToDatabase()
    
  • 替代简单条件分支‌:直接替代仅需返回对象或 null 的条件逻辑‌27。


5. 注意事项

  • 返回值可空性‌:两者均可能返回 null,需配合 ?.?: 处理空值‌46。
  • 性能影响‌:作为内联函数,不会额外增加运行时开销‌28。
  • 代码可读性‌:在复杂条件中,可能不如传统 if 语句直观,需权衡使用场景‌38。

通过合理使用 takeIftakeUnless,可显著提升 Kotlin 代码的简洁性和链式调用的流畅性‌