Kotlin 又要加语法糖了:这次轮到 if-else

Kotlin 一直在改进。

Kotlin 2.5.0-Beta2 中提供了三个实验性的标准库函数(已在 2.5.0-Beta1 的发布记录中列出):

  • onTrue()
  • onFalse()
  • ifOrNull()

它们可以减少重复的 if-else 表达式,让一些常见的 Kotlin 写法更容易读懂。

我发现现代语言在语法糖上有个小趋势,就是支持更多链式调用的写法。

下面用 Android 中的常见场景说明它们的用法。

1. onTrue() 和 onFalse()

它们做什么

假设我们需要根据一个布尔结果执行操作。比如:

  • 登录成功,记录成功日志。
  • 登录失败,记录错误日志。
  • 支付成功,触发埋点事件。

通常,我们会写一个 if-else 代码块来处理。

以前:使用 if-else

有一个 Android 登录页面。验证用户凭据后,我们希望记录认证成功还是失败。

kotlin 复制代码
fun authenticate(user: User, token: String): Boolean {
    val isAuthenticated = verifyToken(user.email, token)
    if (isAuthenticated) {
        logSuccess("Login successful")
    } else {
        logFailure("Login failed")
    }
    return isAuthenticated
}

这段代码没有问题,也是我们已经很熟悉的写法。

现在:使用 onTrue() 和 onFalse()

kotlin 复制代码
@OptIn(ExperimentalStdlibApi::class)
fun authenticate(user: User, token: String): Boolean =
    verifyToken(user.email, token)
        .onTrue {
            logSuccess("Login successful")
        }
        .onFalse {
            logFailure("Login failed")
        }

是不是有点像 Result 的处理方法?

怎么理解

onTrue():

  • 只有布尔值为 true 时,才执行 lambda。
  • 值为 false 时,不执行任何操作。
  • 返回原来的布尔值。

onFalse():

  • 只有布尔值为 false 时,才执行 lambda。
  • 值为 true 时,不执行任何操作。
  • 返回原来的布尔值。

例如:

kotlin 复制代码
@OptIn(ExperimentalStdlibApi::class)
val result = true
    .onTrue { println("Success") }
    .onFalse { println("Failure") }
println(result) // true

其实很简单!

什么时候适合用?这取决于你的喜好和需求,不过可以参考下面几个场景:

  • 记录成功或失败日志。
  • 触发埋点事件。
  • 显示轻量提示。
  • 根据结果执行回调。

如果只是根据 Boolean 值执行操作,并保留原来的布尔结果,就可以考虑这两个函数。

这两个函数适合处理副作用,不会把布尔值转换成其他值。

2. ifOrNull()

它做什么

有时,我们只想在条件成立时返回一个值,条件不成立时返回 null。

比如用户资料页:用户可能填写了电话号码,也可能没有。只有存在联系信息时,我们才希望提供电话号码。

以前:使用 if-else

kotlin 复制代码
val phoneNumber = if (user.hasContactInfo) {
    user.phoneNumber
} else {
    null
}

在 Kotlin 2.5.0-Beta2 中,可以用一种更短的写法。

现在:使用 ifOrNull()

kotlin 复制代码
@OptIn(ExperimentalStdlibApi::class)
val phoneNumber = ifOrNull(user.hasContactInfo) {
    user.phoneNumber
}

怎么理解

可以把 ifOrNull() 理解为一个根据条件提供值的函数:

  • 条件为 true 时,执行 lambda 并返回它的结果。
  • 条件为 false 时,返回 null。
  • 条件为 false 时,不会执行 lambda。

实际场景:映射 API 响应

假设在 Android 开发中,一个 API 返回用户资料。有些用户有联系信息,有些没有。

kotlin 复制代码
data class User(
    val name: String,
    val hasContactInfo: Boolean,
    val phoneNumber: String?
)

我们希望只在存在联系信息时,才为资料页准备要显示的电话号码。

kotlin 复制代码
@OptIn(ExperimentalStdlibApi::class)
fun getDisplayPhoneNumber(user: User): String? {
    return ifOrNull(user.hasContactInfo) {
        user.phoneNumber ?: "No phone number"
    }
}

这样:

  • hasContactInfo 为 true 时,执行 lambda,返回电话号码或兜底文案。
  • hasContactInfo 为 false 时,结果为 null。

映射 API 响应、准备可选的 UI 数据、创建 DTO 时,都可以用到这种写法。

3. 能力速查

函数 作用 返回值
onTrue() 值为 true 时执行操作 原来的布尔值
onFalse() 值为 false 时执行操作 原来的布尔值
ifOrNull() 条件为 true 时执行代码块 代码块的结果或 null

4. 仍处于实验阶段

在 Kotlin 2.5.0-Beta2 中,这些函数仍是实验性 API。使用时需要显式选择启用:

kotlin 复制代码
@OptIn(ExperimentalStdlibApi::class)

也可以在项目中通过编译器选项 -opt-in=kotlin.ExperimentalStdlibApi 统一启用。

本文以 Beta2 版本为例。在生产代码中采用这些 API 前,请先查看最新的 Kotlin 文档,确认它们的状态和用法。

5. 一点想法

这三个函数改动不大,但让常见的 Kotlin 写法更容易表达意图。遇到重复的条件代码块时,可以直接写出要做的事:

  • 成功时执行操作,用 onTrue()。
  • 失败时执行操作,用 onFalse()。
  • 根据条件返回值,用 ifOrNull()。

当然,代码行数并不是唯一的目标,更重要的是让代码容易理解和维护。

还有一点,正如我开头提到的那样,现代语言越来越支持链式调用。写完一个函数调用后,我可以自然地继续使用 . 调用下一个函数去处理结果。在这类场景下,相比使用 if-else,这样的写法确实更简洁,写起来也更流畅。

可能这也是为什么曾经 RxJava 如此流行的原因之一吧。

相关推荐
恋猫de小郭2 小时前
Flutter 3.50 & Dart 3.14 发布,快来看看有什么更新吧
android·前端·flutter
Starry-sky(jing)20 小时前
Vidda ADB 开启:R Pro 65 找不到开发者选项的处理与连接验收
android·adb·远程控制·电视·vidda
雨白20 小时前
从原理到实践:使用 Kotlin KSP 仿写 ButterKnifeLite
android·kotlin
疯华整猫21 小时前
把二十七个 init 从首帧前面搬走:用 Trae 把启动优化钉进 CI
android·性能优化·ai编程
灿飞1 天前
Kotlin与Java虚拟机十一:类与属性:构造顺序、backing field 与显式 backing field
java·后端·kotlin
传奇开心果1 天前
【探秘 Jetpack Compose 框架深水区】 第8课:rememberSaveable 的边界在哪里?——Bundle、Saver 与什么值得跨进程存活
android·kotlin
Frankie_stand1 天前
测试自动化实战指南:从脚本化、自动判据到 CI 集成的完整落地路径
android·ci/cd·自动化
恋猫de小郭1 天前
Flutter 大小核优化又被回滚,然后又开新提案?
android·前端·flutter