当Kotlin的某些事情无效时,我真的陷入困境。当值不能为空时 - 很明显。但是默认情况下,当某些东西可以为null时如何处理情况。看一下这个例子:
abstract class MapActivity: AppCompatActivity(), OnMapReadyCallback {
lateinit var map: GoogleMap
fun initializeMap() {
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
override fun onMapReady(map: GoogleMap?) {
this.map = map //error here
}
}
所以我应该这样处理这种情况:
override fun onMapReady(map: GoogleMap?) {
if (map != null)
this.map = map
}
但是如果地图是 null 怎么办?在这种情况下我该怎么办?我在使用java时遇到过这个问题。
好的,在java中,如果map为null,我们将获得NPE。
对我而言,NPE总比没有好。程序崩溃,这对我来说是一个信号,有些事情是错的,我应该修复它。通过这种方式,我甚至无法追踪我的问题及其发生的原因。 是的,我们可以这样写:
override fun onMapReady(map: GoogleMap?) {
if (map != null) {
this.map = map
} else {
Log.d("Activity","MapIsNull")
}
}
这个代码中有一些含义,是的。 但是我仍然对整个零安全问题犹豫不决。 安全调用例如是奇怪的东西,它产生null和(在我看来)heisenbugs或很难捕获的bug。
有人可以向我解释这里发生了什么,以及使用零安全的最佳做法是什么。
我很确定这件事很有用,因为我不像JB那样聪明
答案 0 :(得分:4)
OnMapReadyCallback的文档明确说明它提供了GoogleMap"的非空实例。因此,onMapReady
方法的参数类型应使用非null类型。
请注意,在Kotlin中实现Java接口时,可以选择是将实现方法的参数声明为nullable还是非null。 IDE将它们标记为可为空,因为它是安全的默认值,但如果您需要它,则可以将它们更改为非null。
答案 1 :(得分:-1)
关于处理空值:让我们假设你需要一个方法fun onMapReady(map: GoogleMap?)
来设置一个类属性map
。
您有两个设计选项可供选择:
1)如果map
为null
class A {
lateinit var map: GoogleMap // never ever `null`
fun onMapReady(map: GoogleMap?) {
map = map!! // throws
}
fun onMapReady2(map: GoogleMap?) {
map = map ?: throw Exception("in case you care for the exception")
}
}
2)Null
对你有特殊意义,可以:
class A {
var map: GoogleMap? = null // map is not ready yet
fun onMapReady(map: GoogleMap?) {
map = map
}
}
当然,如果您的案例是案例(1)并且您可以控制API,那么您永远不应该有一个可以为空的接收者map: GoogleMap?
,因为它会混淆该类的用户。
答案 2 :(得分:-1)
我看到两个不同的问题:
1.无效处理
2.用于空处理的Kotlin特定语法
首先不是kotlin特定的问题。这取决于,@ voddan几乎解释了可用的策略。
关于语法。 如果您只对非空值感兴趣,请使用let()
override fun onMapReady(map: GoogleMap?) {
map?.let { m ->
// do your staff
// 'm' now is definitely not null
}
}
如果您想知道它何时为空,请使用通常的if-else块
override fun onMapReady(map: GoogleMap?) {
if (map != null) {
this.map = map
} else {
Log.d("Activity","MapIsNull")
}
图片的标题说明:
1] @Cedric有关于kotlin的let()和朋友的nice post
2]结账@yole's comment。当在IDEA中重写乐趣时,可以将其标记为“?”,但实际上它们不是。