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,因密封类已覆盖所有可能
}
四、性能优化与注意事项
-
分支顺序
将高频匹配条件放在前面,减少不必要的检查。例如:
scsswhen (statusCode) { 200 -> handleSuccess() 404 -> handleNotFound() else -> handleError() // 低频错误统一处理 }
-
编译优化
Kotlin 编译器将
when
转换为高效的跳转表(类似switch
的tableswitch
),尤其在匹配整数常量时性能接近原生switch
。 -
避免复杂条件
若分支逻辑过于复杂,优先将其封装为独立函数或使用策略模式替代。
五、实际应用场景
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()
}
}
六、常见错误与解决
-
缺少
else
分支(作为表达式时) kotlinval value = when (input) { // 编译错误:缺少 else 1 -> "One" }
-
类型匹配后未自动转换
确保使用
is
后直接访问类型属性:scsskotlinCopy Code when (obj) { is String -> println(obj.length) // 正确:obj 自动转为 String is Int -> println(obj + 1) // 正确:obj 自动转为 Int }
补充
Kotlin的 if 是表达式 有返回值的
总结
Kotlin 的 when
表达式通过以下特性显著提升代码质量:
- 灵活性:支持任意条件表达式、类型检查及范围匹配。
- 安全性:强制覆盖密封类所有子类,减少逻辑遗漏。
- 简洁性 :替代多层
if-else
,提升代码可读性。
合理利用 when
表达式,可以简化复杂逻辑并提高代码可维护性,尤其适用于状态处理、类型检查和模式匹配场景。