在 Kotlin 中,takeUnless
是一个非常实用的标准库内置函数,它与 takeIf
配对使用,用于条件性地返回对象或 null
。它在 Android 开发中常用于安全检查、空值处理和条件过滤。
✅ takeUnless
函数的基本语法
obj.takeUnless { condition }
obj
: 任意对象。condition
: 一个返回Boolean
的 lambda 表达式。- 返回值:
- 如果
condition
为false
,返回obj
本身。 - 如果
condition
为true
,返回null
。
🔁 可以理解为:“除非条件成立,否则就‘拿’这个对象”
🧠 简单记忆方式
函数 | 含义 |
| 如果条件为真,就“拿”这个对象 |
| 除非条件为真(即条件为假时),才“拿”这个对象 |
📌 基本使用示例
val number = 10
// 只有当 number 是奇数时才返回它,否则 null
val oddNumber = number.takeUnless { it % 2 == 0 }
println(oddNumber) // 输出: 10(因为 10 是偶数,条件为 true,所以不取)
val another = 11.takeUnless { it % 2 == 0 }
println(another) // 输出: 11(因为 11 不是偶数,条件为 false,所以取)
val str = "Hello"
str.takeUnless { it.isEmpty() } // 返回 "Hello"(因为不为空)
str.takeUnless { it.length > 3 } // 返回 null(因为长度 > 3,条件为 true)
🚀 Android 开发中的典型应用场景
1. 避免处理空字符串或默认值
val input = editText.text.toString()
val nonEmptyInput = input.takeUnless { it.isBlank() }
nonEmptyInput?.let {
submitData(it)
} ?: showErrorMessage("请输入有效内容")
2. 跳过已初始化的对象
private var userManager: UserManager? = null
fun getUserManager(): UserManager {
return userManager
?.takeUnless { it.isShutdown } // 除非已关闭,否则使用缓存
?: UserManager.newInstance().also { userManager = it }
}
3. 防止重复操作(如防抖)
var lastClickTime = 0L
fun onButtonClicked() {
val now = System.currentTimeMillis()
now.takeUnless { it - lastClickTime < 500 }?.also {
lastClickTime = it
performAction()
}
}
4. 安全地处理文件或资源
file.takeUnless { it.exists() }?.also {
Log.w("File", "文件已存在,跳过创建")
} ?: createNewFile()
5. 条件性地应用样式或配置
textView.text = userInput
.takeUnless { it.contains(prohibitedChars) }
?.also { logSuspiciousInput(it) }
?: "输入无效"
⚖️ takeIf
vs takeUnless
对比
表达式 | 等价写法 |
|
|
|
|
// 两种写法等价:
val result1 = value.takeUnless { it == null }
val result2 = value.takeIf { it != null }
// 它们都实现了“非空则返回,否则 null”
💡 提示:当你发现 takeIf { !condition }
时,建议改用 takeUnless { condition }
,代码更清晰。
✅ 与其他函数结合使用(推荐模式)
// 结合 let 进行条件执行
userInput.takeUnless { it.isBlank() }
?.let { process(it) }
// 结合 also 调试
data.takeUnless { it.isExpired }
?.also { Log.d("Cache", "使用缓存数据") }
?: fetchFromNetwork()
⚠️ 注意事项
- 返回类型是可空的:
takeUnless
返回T?
,即使原对象是非空类型。 - 延迟判断:条件是在调用时才计算。
- 适合替代 if 判断:让代码更函数式、更简洁。
- 不要过度嵌套:保持逻辑清晰。
✅ 总结
特性 | 说明 |
函数类型 | 内联扩展函数 |
所属 | Kotlin 标准库 |
主要用途 | 条件性地获取对象(条件为假时) |
返回值 | 条件为假返回对象,否则 |
常见搭配 |
|
📝 使用口诀
“除非……否则我就用它”
value.takeUnless { it.isNullOrEmpty() }
?.let { safeUse(it) }
“除非它是空的,否则我就用它。”
掌握 takeUnless
能让你的 Kotlin 代码更加安全、简洁、函数式,特别是在 Android 开发中处理用户输入、网络响应、UI 状态时非常有用。它是你工具箱中不可或缺的“守卫”函数之一。