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
,因为它会在不成功时抛出。
我正在尝试处理 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
,因为它会在不成功时抛出。