Kotlin 守卫——更加强大的 when 表达式

2.1.0 版本开始,你可以在带有主题的 when 表达式或语句(when (subject))中使用守护条件。

守护条件允许你为 when 表达式的各个分支设置多个条件,这使得复杂的控制流更加清晰简洁,同时也简化了代码结构。

因为该特性在 2.1.0 版本还是 preview 阶段,所以需要启用此特性:

Kotlin 复制代码
kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xwhen-guards")
    }
}

在完成如上的设置之后,我们便可以使用守卫特性了。

Kotlin 复制代码
sealed interface Animal {
    data class Cat(val mouseHunter: Boolean) : Animal
    data class Dog(val breed: String) : Animal
}

fun feedAnimal(animal: Animal) {
    when (animal) {
        // 仅带有主要条件的分支
        is Animal.Dog -> { println("I eat ${animal.breed}") }
        // 同时带有主要条件和守护条件的分支
        is Animal.Cat if !animal.mouseHunter -> { println("I am a pet eat cat food") }
        // 如果上述条件均不匹配
        is Animal.Cat -> println("I eat mouse")
    }
}

fun main() {
    feedAnimal(Animal.Cat(true))
    feedAnimal(Animal.Cat(false))
    feedAnimal(Animal.Dog("Meat"))
}

// Output
// I eat mouse
// I am a pet eat cat food
// I eat Meat

在单个 when 表达式中,你可以组合带有和不带有守护条件的分支。只有当主要条件和守卫条件都为真时,带有守护条件的分支中的代码才会运行。如果主要条件不匹配,则不会计算守护条件。此外,守护条件支持 else if

上述代码中,最后一个语句是 is Animal.Cat,此时你可以不用写 else 语句,因为编译器会检查你的 when 表达式是否穷尽。

为什么不用 && ?

有的编程语言使用了 && 作为守卫表达式的连接符,Kotlin 此处使用了 if,为什么呢?

Kotlin 复制代码
var a = 10
when {
    a < 100 && a > 0 -> {
        println("under 100")
    }
    else -> {
        println("others")
    }
}

Kotlin 在无主题的 when 表达式中,判断条件就是使用 && 作为连接符的,同时,在守卫条件中,if 表达式如果有多个条件,也需要使用 && 或者 ||

Kotlin 复制代码
var a = 10
when(a) {
    is Long if (a < 100 && a > 0) -> {
        println("under 100")
    }
    else -> {
        println("others")
    }
}

如果 Kotlin 选择 && 作为守卫的连接符,那么在编写多条件时,可读性就会大大降低,也不利于理解。

相关推荐
修炼者23 分钟前
Kotlin中的Flow流
android·kotlin
洞见不一样的自己25 分钟前
Android studio 编译问题
android
j***630827 分钟前
SpringbootActuator未授权访问漏洞
android·前端·后端
YJlio1 小时前
进程和诊断工具学习笔记(8.29):ListDLLs——一眼看清进程里加载了哪些 DLL,谁在偷偷注入
android·笔记·学习
你的乔克叔叔2 小时前
四大组件-Activity
android
aqi002 小时前
FFmpeg开发笔记(九十二)基于Kotlin的开源Android推流器StreamPack
android·ffmpeg·kotlin·音视频·直播·流媒体
Aileen_0v04 小时前
【Gemini3.0的国内use教程】
android·人工智能·算法·开源·mariadb
浩浩的代码花园5 小时前
自研端侧推理模型实测效果展示
android·深度学习·计算机视觉·端智能
踢球的打工仔11 小时前
PHP面向对象(7)
android·开发语言·php
安卓理事人11 小时前
安卓socket
android