为什么这个Kotlin代码仍然需要? 访问成员?
我在Kotlin类中有以下function:
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
足以确保?.
是不必要的?
首先,请注意检查和使用情况会得到属性值两次。 由于_activity
是一个var
,它可以在检查和使用之间重新分配(可能由另一个线程)。 使用属性值不是无效的,因为它可能不是被检查的值,编译器要求你再次检查值。
换句话说,编译器不能将 _activity
转换为非空types。
你可以通过在一个局部variables中存储这个值来解决这个问题(它不能从外部改变,所以编译器可以certificate它是相同的值):
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
也可以看看:
-
最好的方法来处理这种情况下,“聪明的演员是不可能的”
-
科特林,聪明的演员是不可能的,因为复杂的expression
-
在Kotlin中,处理可空值的惯用方式是什么,引用或转换它们