Kotlin 为什么尽管进行空检查仍需要非空断言

Kotlin why non-null assertion required despite null check

我正在尝试处理 Kotlin/Android 上的改造响应:

if (response.isSuccessful && response.body() != null) {
                    val result = response.body().result

首先我不明白为什么响应可以成功而body为空。无论如何,如果我添加空检查,我也会得到“智能转换为 'xy' 是不可能的,因为 'response.body()' 是一个复杂的表达式” 添加非空断言代码 (!!) 实际上对我来说这是两个单独的警告,但为什么是空断言请求?

您需要将 response.body() 设置为一个变量,然后检查其是否为 nulability:

val body = response.body()
if (response.isSuccessful && body != null) {
    val result = body.result
}

编译器无法知道 body() 每次都保证 return 相同,因此它无法将其智能转换为非空值。此外,如果 isSuccessful 为真,它不知道正文不会为空这一事实。

因为我们从这个库的文档中知道它总是一样的,所以使用 !! 是安全的。但是您也可以将该值复制到局部变量并在您的空检查中使用该变量。这样即使您误解了文档,您也可以确定您的代码是安全的。

我自己并没有真正使用 Retrofit,但是通过阅读它,我知道您可以在 Kotlin 中通过使用挂起函数更自然地使用它,然后您就不必再工作了带有回调和 Response 对象。因此,不是创建一个 return 是 Call<MyData> 的函数,然后将调用排队,监听 success/failure,然后在成功时展开主体;相反,您可以直接将函数标记为 suspend 和 return MyData。在进行函数调用时使用 try/catch 或 runCatching,因为它会在不成功时抛出。