Kotlin 之 when 表达式

Kotlin 的 when 表达式是一种强大的条件控制结构,可以替代传统的 switch-case 语句,并支持更灵活的条件匹配逻辑。以下是其核心特性及用法:


‌一、基础语法与对比‌

1. ‌与 Java switch 的对比‌
‌特性‌ ‌**Kotlin when**‌ ‌**Java switch**‌
‌支持类型‌ 任意类型(包括非枚举、非整型) 仅支持整型、枚举、字符串(Java 7+)
‌分支条件‌ 可为表达式(如范围、类型、复杂逻辑) 仅常量值
‌默认分支‌ 可选的 else(作为表达式时需覆盖所有情况) 必须显式处理未覆盖情况或使用 default
‌返回值‌ 可作为表达式返回值 仅流程控制,无返回值
2. ‌基本语法‌
rust 复制代码
rust
 代码解读
复制代码
// 作为表达式(必须有 else)
val result = when (input) {
    1 -> "One"
    2 -> "Two"
    else -> "Unknown"
}

// 作为语句(else 可选)
when (x) {
    0 -> println("Zero")
    1 -> println("One")
    else -> println("Other")
}

‌二、高级匹配模式‌

1. ‌多条件匹配‌

使用逗号 , 或 in 合并多个条件:

rust 复制代码
rust
 代码解读
复制代码
when (value) {
    0, 1 -> "Binary digit"     // 匹配 0 或 1
    in 2..10 -> "Single digit" // 匹配 2~10
    is String -> "String type"  // 类型匹配
    else -> "Unknown"
}
2. ‌类型检查与智能转换‌

结合 is 进行类型判断后,自动完成类型转换:

kotlin 复制代码
kotlin
 代码解读
复制代码
fun process(obj: Any) = when (obj) {
    is Int -> "Int: ${obj * 2}"       // obj 自动转为 Int
    is String -> "String: ${obj.length}" // obj 自动转为 String
    else -> "Unknown type"
}
3. ‌无参数模式‌

当 when 不传参数时,每个分支条件需为布尔表达式:

rust 复制代码
rust
 代码解读
复制代码
when {
    score >= 90 -> "A"
    score >= 80 -> "B"
    score >= 60 -> "C"
    else -> "D"
}
4. ‌结合范围(Range) ‌

使用 in 或 !in 检查值是否在区间内:

rust 复制代码
rust
 代码解读
复制代码
val temperature = 25
val status = when (temperature) {
    in -10..0 -> "Freezing"
    in 1..15 -> "Cold"
    in 16..25 -> "Warm"
    else -> "Hot"
}

‌三、与密封类(Sealed Class)结合‌

when 可强制覆盖密封类的所有子类,避免遗漏分支(无需 else):

kotlin 复制代码
kotlin
 代码解读
复制代码
sealed class Result {
    data class Success(val data: String) : Result()
    data class Error(val message: String) : Result()
}

fun handleResult(result: Result) = when (result) {
    is Result.Success -> "Data: ${result.data}"
    is Result.Error -> "Error: ${result.message}"
    // 无需 else,因密封类已覆盖所有可能
}

‌四、性能优化与注意事项‌

  1. ‌分支顺序 ‌

    将高频匹配条件放在前面,减少不必要的检查。例如:

    scss 复制代码
    scss
     代码解读
    复制代码
    when (statusCode) {
        200 -> handleSuccess()
        404 -> handleNotFound()
        else -> handleError() // 低频错误统一处理
    }
  2. ‌编译优化 ‌

    Kotlin 编译器将 when 转换为高效的跳转表(类似 switch 的 tableswitch),尤其在匹配整数常量时性能接近原生 switch。

  3. ‌避免复杂条件 ‌

    若分支逻辑过于复杂,优先将其封装为独立函数或使用策略模式替代。


‌五、实际应用场景‌

1. ‌**替代多层 if-else**‌

简化复杂的条件链:

ini 复制代码
ini
 代码解读
复制代码
// 传统 if-else
if (user.role == "Admin") { ... }
else if (user.role == "Editor" && user.isActive) { ... }
else { ... }

// 使用 when 更清晰
when {
    user.role == "Admin" -> ...
    user.role == "Editor" && user.isActive -> ...
    else -> ...
}
2. ‌处理枚举类型‌

清晰匹配枚举值:

kotlin 复制代码
kotlin
 代码解读
复制代码
enum class Direction { NORTH, SOUTH, EAST, WEST }

fun move(direction: Direction) = when (direction) {
    Direction.NORTH -> "Move up"
    Direction.SOUTH -> "Move down"
    Direction.EAST, Direction.WEST -> "Move horizontally"
}
3. ‌Android 开发中的典型用法‌

处理点击事件或状态:

kotlin 复制代码
kotlin
 代码解读
复制代码
override fun onClick(view: View) {
    when (view.id) {
        R.id.btn_submit -> submitForm()
        R.id.btn_cancel -> closeActivity()
        R.id.btn_retry -> loadData()
    }
}

‌六、常见错误与解决‌

  1. ‌缺少 else 分支(作为表达式时) ‌

    kotlin 复制代码
    kotlin
     代码解读
    复制代码
    val value = when (input) {  // 编译错误:缺少 else
        1 -> "One"
    }
  2. ‌类型匹配后未自动转换 ‌

    确保使用 is 后直接访问类型属性:

    scss 复制代码
    scss
     代码解读
    复制代码
    kotlinCopy Code
    when (obj) {
        is String -> println(obj.length) // 正确:obj 自动转为 String
        is Int -> println(obj + 1)       // 正确:obj 自动转为 Int
    }

补充

Kotlin的 if 是表达式 有返回值的

‌总结‌

Kotlin 的 when 表达式通过以下特性显著提升代码质量:

  • ‌灵活性‌:支持任意条件表达式、类型检查及范围匹配。

  • ‌安全性‌:强制覆盖密封类所有子类,减少逻辑遗漏。

  • ‌简洁性 ‌:替代多层 if-else,提升代码可读性。

相关推荐
福兮说6 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理6 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆6667 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)7 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan8 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_8 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒8 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技9 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
yivifu9 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
默_笙10 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript