为什么这个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足以确保?. 是不必要的?

One Solution collect form web for “为什么这个Kotlin代码仍然需要? 访问成员?”

首先,请注意检查和使用情况会得到属性值两次。 由于_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中,处理可空值的惯用方式是什么,引用或转换它们

  • Kotlin的部分class级代表团
  • 匕首注射不适用于Kotlin的“物体”
  • 为什么不outlook未来,在科特林的正则expression式工作?
  • 如何用kotlin标记List
  • Android Plugin 2.2.0-alpha1无法与Kotlin编译
  • 错误:在使用Kotlin编译Java代码时,-source 1.3中不支持generics
  • 从Kotlin类调用方法
  • 如何使用kotlin将layoutmanager设置为RecycleView
  • 如何检测Data class Kotlin中更改的值?
  • 在JSON数据类中带有可选字段的types安全
  • Jsoup中的属性值的字符集
  • Kotlin language will be the best programming language for Android.