我在Kotlin课程中有以下功能:
private fun raiseResponse(ex: Exception, resObj: JSONObject) {
if (_activity == null || _responseHandler == null) return
_activity.runOnUiThread {
_responseHandler.invoke(ex, resObj)
}
}
_activity
和_responseHandler
都定义为:
var _activity: Activity? = null
var _responseHandler: ((Exception, JSONObject) -> Unit)? = null
但是,调用runOnUiThread
的行只会在我使用?.
而不是.
时进行编译。
我尝试过谷歌搜索,但我担心我的术语不足。我假设raiseResponse
第一行的空检查足以确保?.
不必要吗?
答案 0 :(得分:4)
首先,请注意检查和使用情况两次获取属性的值。由于_activity
是var
,因此可以在检查和使用之间重新分配(可能由另一个线程)。使用属性值不是空安全的,因为它可能不是已检查的值,编译器要求您再次检查该值。
换句话说,编译器不能smart-cast _activity
为非可空类型。
你可以通过将值存储在局部变量中来解决这个问题(它不能从外部更改,因此编译器可以证明它的值相同):
val activity = _activity
if (activity == null || _responseHandler == null) return
activity.runOnUiThread {
_responseHandler.invoke(ex, resObj)
}
或者,等效地使用像?.let { ... }
这样的成语:
_activity?.let { activity ->
if (_responseHandler == null) return
activity.runOnUiThread { // safe, because it is surely the same value
_responseHandler.invoke(ex, resObj)
}
} ?: return
另见: