Kotlin 之 when 表达式

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


一、基础语法与对比

1. ‌与 Java switch 的对比
特性 ‌**Kotlin when**‌ ‌**Java switch**‌
支持类型 任意类型(包括非枚举、非整型) 仅支持整型、枚举、字符串(Java 7+)
分支条件 可为表达式(如范围、类型、复杂逻辑) 仅常量值
默认分支 可选的 else(作为表达式时需覆盖所有情况) 必须显式处理未覆盖情况或使用 default
返回值 可作为表达式返回值 仅流程控制,无返回值
2. ‌基本语法
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 复制代码
when (value) {
    0, 1 -> "Binary digit"     // 匹配 0 或 1
    in 2..10 -> "Single digit" // 匹配 2~10
    is String -> "String type"  // 类型匹配
    else -> "Unknown"
}
2. ‌类型检查与智能转换

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

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 复制代码
when {
    score >= 90 -> "A"
    score >= 80 -> "B"
    score >= 60 -> "C"
    else -> "D"
}
4. ‌结合范围(Range)

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

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 复制代码
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 复制代码
    when (statusCode) {
        200 -> handleSuccess()
        404 -> handleNotFound()
        else -> handleError() // 低频错误统一处理
    }
  2. 编译优化

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

  3. 避免复杂条件

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


五、实际应用场景

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

简化复杂的条件链:

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 复制代码
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 复制代码
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 复制代码
    val value = when (input) {  // 编译错误:缺少 else
        1 -> "One"
    }
  2. 类型匹配后未自动转换

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

    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,提升代码可读性。

合理利用 when 表达式,可以简化复杂逻辑并提高代码可维护性,尤其适用于状态处理、类型检查和模式匹配场景。

相关推荐
louisgeek14 小时前
Kotlin Flow 操作符 map 和 flatMap 的区别
kotlin
帅次14 小时前
Flutter DropdownButton 详解
android·flutter·ios·kotlin·gradle·webview
QING61815 小时前
Kotlin groupBy用法及代码示例
android·kotlin·源码阅读
QING61815 小时前
Kotlin getOrElse用法及代码示例
android·kotlin·源码阅读
QING61815 小时前
Kotlin getOrNull用法及代码示例
android·kotlin·源码阅读
QING61815 小时前
Kotlin getValue用法及代码示例
android·kotlin·源码阅读
QING61815 小时前
Kotlin getOrPut用法及代码示例
android·kotlin·源码阅读
QING61815 小时前
Kotlin groupingBy用法及代码示例
android·kotlin·源码阅读
渔舟小调15 小时前
针对vue 、 kotlin 、java 这三个语言AI辅助开发的提示词
java·vue.js·kotlin
祖师爷科技15 小时前
kotlin扩展函数的实现原理
android·kotlin