当前位置: 首页 > news >正文

彻底讲清楚 Kotlin 的 when 表达式

一、一句话理解 when

when 是 Kotlin 中的“超级 switch”:它不仅能替代 if-else 和 Java 的 switch,还能返回值、匹配任意条件、甚至当表达式用!

它是 Kotlin 最常用、最优雅的控制流工具之一


二、基础用法:替代 if-elseswitch

✅ 1. 基本匹配(类似 switch)
val grade = "A"when (grade) {"A" -> println("优秀")"B" -> println("良好")"C" -> println("及格")else -> println("不及格")
}

🔔 注意:不需要 break!Kotlin 自动“穿透”问题。

✅ 2. 多个值合并
when (x) {1, 2, 3 -> println("小数字")4, 5 -> println("中等数字")else -> println("其他")
}
✅ 3. 区间匹配(超实用!)
val score = 85when (score) {in 90..100 -> "A"in 80..89 -> "B"in 70..79 -> "C"else -> "D"
}
✅ 4. 类型检查(Android 高频!)
when (view) {is TextView -> view.text = "Hello"is ImageView -> view.setImageResource(R.drawable.icon)is Button -> view.isEnabled = trueelse -> Log.w("UnknownView", view::class.java.simpleName)
}

✅ 自动类型智能转换(smart cast):is TextView 后,view 直接就是 TextView 类型!


三、when 是表达式!可以返回值 💡

这是 Kotlin when 最强大的特性之一:

val result = when (status) {LOADING -> "加载中..."SUCCESS -> "成功!"ERROR -> "出错了"else -> "未知状态"
}// 直接用于 UI
textView.text = when (user.role) {"admin" -> "管理员""user" -> "普通用户"else -> "访客"
}

每个分支必须有值(或抛异常),否则编译报错!


四、高级用法:任意条件匹配(不限于等值)

when 的每个分支可以是任意布尔表达式

val age = 25val category = when {age < 13 -> "儿童"age < 18 -> "青少年"age < 60 -> "成年人"else -> "老年人"
}

🔥 这相当于 if-else if-else,但更清晰!

Android 实战:权限检查
val message = when {ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED ->"相机已授权"shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) ->"请允许相机权限以使用扫码功能"else ->"需要相机权限,请在设置中开启"
}
showDialog(message)

五、配合密封类(Sealed Class)—— Android 状态管理黄金组合!

这是现代 Android 开发(尤其 Jetpack Compose)中最推荐的模式:

sealed class UiState {object Loading : UiState()data class Success(val data: List<Item>) : UiState()data class Error(val msg: String) : UiState()
}// 在 Compose 中
@Composable
fun MyScreen(viewModel: MyViewModel) {val uiState by viewModel.uiState.collectAsState()when (uiState) {is UiState.Loading -> CircularProgressIndicator()is UiState.Success -> LazyColumn {items(uiState.data) { item -> ItemCard(item) }}is UiState.Error -> ErrorMessage(uiState.msg)}
}

✅ 优势:

  • 编译器检查全覆盖:如果你加了新状态,不处理就报错!
  • 类型安全is Success 后自动解构出 data
  • 代码清晰:状态 → UI 一一对应

六、常见陷阱 & 最佳实践

❌ 陷阱1:忘记 else(当 when 用作表达式时)
val msg = when (status) {LOADING -> "加载中"SUCCESS -> "成功"// ❌ 编译错误!缺少 else 或 ERROR 分支
}

✅ 解决:确保所有可能值都被覆盖,或加 else

❌ 陷阱2:在 when 中做复杂逻辑(降低可读性)
when (user) {is Admin -> {// 20 行代码...}is Guest -> {// 15 行代码...}
}

✅ 建议:提取成函数

when (user) {is Admin -> handleAdmin(user)is Guest -> handleGuest()
}
✅ 最佳实践1:优先用 when 替代长 if-else
// 不好
if (type == "image") { ... }
else if (type == "video") { ... }
else if (type == "text") { ... }// 好
when (type) {"image" -> ..."video" -> ..."text" -> ...
}
✅ 最佳实践2:结合 let 处理 nullable
when (val user = fetchUser()) {null -> showLogin()else -> showProfile(user) // user 自动非空
}

七、对比 Java 的 switch

特性Java switchKotlin when
支持字符串✅(Java 7+)
支持对象✅(通过 equals
支持区间✅(in 1..10
支持类型检查✅(is String
支持任意表达式✅(when { x > 0 -> ... }
返回值✅(表达式!)
自动 break❌(需手动)✅(无穿透)

📌 Kotlin 的 when 完全碾压 Java 的 switch


八、总结一句话

when 是 Kotlin 中集“模式匹配 + 表达式返回 + 类型智能转换”于一体的控制流神器,配合密封类,能写出安全、简洁、可维护性极高的 Android 代码。

从状态管理到权限处理,从 UI 渲染到数据转换 —— when 无处不在


💡 小练习:用 when 重构这段代码

if (errorCode == 404) {message = "页面不存在"
} else if (errorCode == 500) {message = "服务器错误"
} else if (errorCode in 400..499) {message = "请求错误"
} else {message = "未知错误"
}

✅ 重构后:

val message = when (errorCode) {404 -> "页面不存在"500 -> "服务器错误"in 400..499 -> "请求错误"else -> "未知错误"
}

是不是更清爽?😊

http://www.dtcms.com/a/572627.html

相关文章:

  • 济宁网站建设 果壳科技腾讯云主机
  • 百度收录不到我的网站聊大 网站设计
  • Jackson SerializerModifier 拦截器(高性能)实现时间戳自动添加
  • 虚拟机server2012 安装oracle11g遇到的坑
  • Webpack中各种devtool配置的含义与SourceMap生成逻辑
  • 深入理解 PostgreSQL Tuple 与 Dead Tuple:检测方法与 VACUUM 自动化实践
  • 系统分析师-案例分析-数据库系统数据仓库反规范化技术NoSQL内存数据库
  • 用Python来学微积分32-定积分的可积性条件详解
  • 游戏远程操控性能横评:ToDesk、Parsec、UU远程深度对比
  • 【C/C++刷题集】二叉树算法题(二)
  • Django登录注册完整代码(图片、邮箱验证、加密)
  • 基于Optuna 贝叶斯优化的自动化XGBoost 超参数调优器
  • Qt开发初识
  • ReactNative 快速入门手册
  • 【C++:map和set的使用】C++ map/multimap完全指南:从红黑树原理入门到高频算法实战
  • GPT-OSS大模型Attention架构设计
  • 基于Mask R-CNN和TensorRT的高效草莓实例分割
  • RV1126 NO.38:OPENCV查找图形轮廓重要API讲解
  • 腾讯WAIC发布“1+3+N”AI全景图:混元3D世界模型开源,具身智能平台Tairos亮相
  • 各种开源闭源大模型,包括自己本地部署的一些8b 14b模型,支持函数调用(功能调用)function call吗?
  • Spring Boot 深度剖析:从虚拟线程到声明式 HTTP 客户端,再到云原生最优解
  • 创新的商城网站建设网站页面怎么设计
  • 2016年网站建设总结php网站开发工资多少
  • 线程3.1
  • Kubernetes基础概念和命令
  • 技术干货-MYSQL数据类型详解
  • 备份工具:rsync、Tar、Borg、Veeam 备份与恢复方案
  • 深入 Pinia 工作原理:响应式核心、持久化机制与缓存策略
  • 【前端】动态插入并渲染大量数据的方法-时间分片:使用requestAnimationFrame+DocumentFragment
  • 耶鲁大学Hello Robot研究解读:人类反馈策略的多样性与有效性