Kotlin内置函数之takeIf 和 takeUnless

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

sql 复制代码
// 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。

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

  • 示例‌:

kotlin 复制代码
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。

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

  • 示例‌:

kotlin 复制代码
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。

    ini 复制代码
    // 传统 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。

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


5. 注意事项

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

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

相关推荐
投笔丶从戎1 小时前
Kotlin Multiplatform--03:项目实战
android·开发语言·kotlin
居然是阿宋2 小时前
Android Canvas API 详细说明与示例
android
wuli玉shell4 小时前
spark-Schema 定义字段强类型和弱类型
android·java·spark
东风西巷5 小时前
BLURRR剪辑软件免费版:创意剪辑,轻松上手,打造个性视频
android·智能手机·音视频·生活·软件需求
JhonKI5 小时前
【MySQL】行结构详解:InnoDb支持格式、如何存储、头信息区域、Null列表、变长字段以及与其他格式的对比
android·数据库·mysql
ab_dg_dp6 小时前
Android 位掩码操作(&和~和|的二进制运算)
android
潜龙952718 小时前
第3.2.3节 Android动态调用链路的获取
android·调用链路
追随远方18 小时前
Android平台FFmpeg音视频开发深度指南
android·ffmpeg·音视频
撰卢19 小时前
MySQL 1366 - Incorrect string value:错误
android·数据库·mysql
恋猫de小郭20 小时前
Flutter 合并 ‘dot-shorthands‘ 语法糖,Dart 开始支持交叉编译
android·flutter·ios