Kotlin 判空写法对比与最佳实践

在业务代码中,我们经常遇到可空对象的判空与处理。以下通过 updateRobotStatusResponse 的示例,总结三种推荐写法、优缺点对比以及团队实践建议。

写法一:let 操作符(推荐)

Kotlin 复制代码
fun updateRobotStatusResponse(response: RobotStatusResponse?) {
    response?.let { resp ->
        if (resp.isSuccess()) {
            // 成功处理
            _robotStatusResponse.postValue(resp)
            Log.d(TAG, "机器人状态响应更新成功")
        } else {
            // 失败处理
            Log.e(TAG, "新系统机器人状态获取失败: ${resp.errorMessage}")
        }
    } ?: run {
        // response 为 null 的处理
        Log.e(TAG, "新系统机器人状态获取失败: response为null")
    }
}

优点:

  • 空安全:只在非空时执行逻辑。

  • 作用域清晰:resp 在块内非空。

  • Kotlin 风格统一,简洁易懂。

适用场景:逻辑不复杂,需要兼顾可读性和简洁性的情况。

写法二:先判断 null(守卫式)

Kotlin 复制代码
fun updateRobotStatusResponse(response: RobotStatusResponse?) {
if (response == null) {
Log.e(TAG, "新系统机器人状态获取失败: response为null")
return
}

if (response.isSuccess()) {
_robotStatusResponse.postValue(response)
Log.d(TAG, "机器人状态响应更新成功")
} else {
Log.e(TAG, "新系统机器人状态获取失败: ${response.errorMessage}")
}
}

优点:

  • 直观,先处理边界条件。

  • 提前返回,减少嵌套层次。

  • 结构清晰,易维护。

适用场景:逻辑较复杂,判空后需要快速返回的场景。

写法三:Elvis 操作符

Kotlin 复制代码
fun updateRobotStatusResponse(response: RobotStatusResponse?) {
if (response?.isSuccess() == true) {
_robotStatusResponse.postValue(response)
Log.d(TAG, "机器人状态响应更新成功")
} else {
val errorMsg = response?.errorMessage ?: "response为null"
Log.e(TAG, "新系统机器人状态获取失败: $errorMsg")
}
}

优点:

  • 简洁,一行处理多种情况。

  • 统一,失败分支集中在一起。

适用场景:简单逻辑,团队习惯"精简风格"时。

不推荐写法:when 过度使用

Kotlin 复制代码
fun updateRobotStatusResponse(response: RobotStatusResponse?) {
when {
response == null -> Log.e(TAG, "新系统机器人状态获取失败: response为null")
response.isSuccess() -> {
_robotStatusResponse.postValue(response)
Log.d(TAG, "机器人状态响应更新成功")
}
else -> Log.e(TAG, "新系统机器人状态获取失败: ${response.errorMessage}")
}
}

问题:

  • 结构冗余,信息增益小。

  • 容易演变为"全局开关",不利于维护。

推荐结论

  • 优先 :let 写法 ------ 简洁、空安全、Kotlin 风格。

  • 复杂逻辑:守卫式写法 ------ 边界先行、可维护性更强。

  • 次选:Elvis 操作符 ------ 适合简单快速场景。

  • 避免 :when 判空,除非确实存在三种以上复杂分支。

相关推荐
Sarvartha6 分钟前
Object 类
java·开发语言
知守观8 分钟前
feign-core 就在依赖树里,运行时却找不到类:一次 provided scope 引发的启动失败排查
java·spring cloud·maven
她的男孩9 分钟前
企业接口照样拦得住:独立 Flyway、@RequiresFeature 与离线许可证
java·spring boot·后端
十年Java程序媛10 分钟前
Lambda 与函数式接口|别只会复制 ()->{},底层规则和坑一次性讲清
java·spring boot·后端
墨天梦16 分钟前
D03_Compose列表与稳定身份
android·gitee·kotlin
Nozokime17 分钟前
ThreadLocal 在流式 Agent 里静默失效:LangChain4j 轨迹埋点的零侵入方案
java
小宋102122 分钟前
OpenTelemetry GenAI可观测性实战:串起模型、工具、Token与错误
java·人工智能·算法·贪心算法
m0_5873830040 分钟前
工业场景设备维修维护实战技巧 全流程标准化落地与常见问题排查指南
java·spring·小程序·架构·需求分析
萌新杰少1 小时前
Kuikly股票查看软件开发体验——SaiRen
android·kotlin·客户端
vilya1 小时前
把 Python 塞进 APK:Chaquopy 打包实践
android·python