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 表达式,可以简化复杂逻辑并提高代码可维护性,尤其适用于状态处理、类型检查和模式匹配场景。

相关推荐
0wioiw01 小时前
Kotlin基础(①)
android·开发语言·kotlin
张力尹5 小时前
关于 MutableSharedFlow 的 tryEmit 和 emit 争议说法
android·面试·kotlin
老码识土10 小时前
Kotlin 协程源代码泛读:Continuation 思想实验
android·kotlin
老码识土10 小时前
Kotlin 协程源代码泛读:async
android·kotlin
划水哥~10 小时前
Activity之间交互
android·kotlin
氦客20 小时前
kotlin知识体系(六) : Flow核心概念与与操作符指南
android·开发语言·kotlin·协程·flow·冷流·热流
魔道不误砍柴功1 天前
Java 2025:解锁未来5大技术趋势,Kotlin融合&AI新篇
java·人工智能·kotlin
wangz761 天前
Gradle 中添加生成 jar 报错
kotlin·gradle·jar
氦客1 天前
kotlin知识体系(五) :Android 协程全解析,从作用域到异常处理的全面指南
android·开发语言·kotlin·协程·coroutine·suspend·functions
盒子里的猫有猫版1 天前
kotlin学习——空安全
kotlin