在业务代码中,我们经常遇到可空对象的判空与处理。以下通过 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
判空,除非确实存在三种以上复杂分支。