Kotlin 警告:对标记类型的非空接收器进行不必要的安全调用

Sco*_*ggs 1 null kotlin android-studio

和其他人一样,我正在学习 Kotlin。我正在努力做对。所以我在我的班级中声明了一个变量:

private lateinit var mLastMarker: Marker
Run Code Online (Sandbox Code Playgroud)

mLastMarker 会跟踪我上次使用标记的时间,因此我可以在制作新标记时将其删除(谷歌地图 api)。因此,在添加新标记时,我首先要删除旧标记:

// remove last marker (if it exists)
mLastMarker?.remove()

// add this marker to the map
mLastMarker = mMap.addMarker(markerOptions)
Run Code Online (Sandbox Code Playgroud)

这对我来说很有意义。我在想,remove()如果mLastMarker不为空,我只会执行该函数。它将在之后立即设置,因此remove()每次在第一个之后都会调用(当有东西要删除时)。

但我收到警告。以?.标题中的警告消息突出显示。是什么赋予了?我在这里遗漏了 kotlin 的空安全性什么?

zsm*_*b13 5

使用lateinitnull值将永远不会存储在您的财产中。请注意,它的类型 ,Marker不是可空Marker?类型 - 事实上,您无法创建既可以为空又可以为lateinit.

通过使用lateinit,您是说编译器不必在任何时候检查可空性,并且您总是期望在您阅读属性之前已经存在一个值。如果您在设置之前阅读它,您将不会得到null,而是会抛出异常。如果您给它一个值,您也永远不能将它设置回未初始化状态,因为它不会接受null作为新值。

一般来说,lateinit如果您想在开始使用某个东西之前对其进行一次初始化,但由于某种原因无法在创建该属性时对其进行初始化(例如,在一个类的构建时),这是很好的。

如果您有时必须检查当前是否有一个值,那么使用可空属性可能会更好(尽管您可以从技术上检查lateinit变量是否已初始化,但它并不漂亮)。

  • 啊,我不太明白lateinit是如何工作的。现在我懂了。根据记录,我真正想要的是将我的变量初始化为 null 并检查它是否已使用。所以我的声明是`private var mLastMarker:Marker?= null`,第一个用法现在是`mLastMarker?.remove()`,这对我来说非常有意义。 (2认同)