kotlin - 在 Kotlin 中将“lateinit”修饰符与条件绑定
问题描述
在 Kotlin 中,我们有lateinit
对惰性变量初始化的修饰符,而不是var something: Something? = null
.
在我的情况下,我有一个 的列表Element
,并且我想在拥有第一个对象时将其分配给变量。lateinit
所以,我尝试了几种方法来实现这一点。
首先,使用“firstOrNull()”方法
lateinit var applicationHolder: ApplicationHolder
applicationHolder = env.getElementsAnnotatedWith(InjectApplication::class.java)
.map {
ApplicationHolder(it, (it as TypeElement).asClassName(), it.simpleName.toString()).apply {
val component = it.getAnnotation(InjectApplication::class.java).getComponent()
componentClass = component
}
}.firstOrNull()
第一个解决方案失败了,因为applicationHolder
不接受 Nullable 类型的 ApplicationHolder。(类型推断失败。预期类型不匹配:推断类型为 ApplicationHolder?但应为 ApplicationHolder。)
虽然我可以使用first
而不是firstOrNull
来实现这一点,但它太危险了,因为列表可能是空的。
二、使用if-condition
val item = env.getElementsAnnotatedWith(InjectApplication::class.java)
.map {
ApplicationHolder(it, (it as TypeElement).asClassName(), it.simpleName.toString()).apply {
val component = it.getAnnotation(InjectApplication::class.java).getComponent()
componentClass = component
}
}.firstOrNull()
if (item != null) {
applicationHolder = item
}
第二个解决方案成功编译并运行良好。
三、使用支持属性(其实这个解决方案不使用lateinit修饰符)
val applicationHolder: ApplicationHolder
get() {
return _applicationHolder ?: throw NullPointerException("Not initialized")
}
private var _applicationHolder: ApplicationHolder? = null
_applicationHolder = env.getElementsAnnotatedWith(InjectApplication::class.java)
.map {
ApplicationHolder(it, (it as TypeElement).asClassName(), it.simpleName.toString()).apply {
val component = it.getAnnotation(InjectApplication::class.java).getComponent()
componentClass = component
}
}.firstOrNull()
第三个解决方案成功编译并运行良好。
简而言之,我的问题如下。
- 有没有比这些解决方案更好的解决方案来实现我的目标?
- 如果不存在另一个解决方案,哪个是干净或更好的解决方案?我可以使用第二种或第三种解决方案,但我没有信心哪个是干净的或更好的。
解决方案
你为什么在这里使用 lateinit 而不是可以为空的类型?
这给我敲响了警钟:
这太危险了,因为列表可能为空。
如果你试图访问一个 lateinit 对象而不初始化它,你的应用程序将会崩溃。如果肯定会初始化 Lateinit,则应该使用它。
我会将代码更改为您避免的代码:var something: Something? = null
然后使用 firstOrNull() 方法。kotlin 空安全类型系统将强制您处理空值,从而生成安全代码!
推荐阅读
- reactjs - 如何将 2 个函数作为道具传递给 touchableOpacity?
- google-cloud-pubsub - Airflow:创建一个 Operator,它根据 hook 结果返回一个传感器或一个 DummyOperator
- tarantool - 如何使用 go-tarantool 在 Tarantool 中插入 UUID?
- javascript - 无法解构“e.target”的属性“名称”,因为它未定义
- c - Atmega328p 仅处理一个 ISR
- python - 将 Django ModelSerializer 序列化为 json?
- javascript - 根据选择标准添加值
- hashicorp-vault - 如何防止hashicorp保险库密封?
- amazon-web-services - 在多线程烧瓶应用程序中请求数据似乎很脏
- r - flextable::save_as_image() 包括 Rmarkdown 编织到 Word 时的图像路径