猫王运算符与非空断言:这些语句之间的区别?
Posted
技术标签:
【中文标题】猫王运算符与非空断言:这些语句之间的区别?【英文标题】:Elvis Operator vs Non-Null Assertion: Diff Between These Statements? 【发布时间】:2018-12-25 19:21:29 【问题描述】:试图理解 Kotlin 中的 null 安全性:以下两个语句似乎都可以正常工作并且在我的程序中可以互换:
var y1: Double = 0.0
get() = when(hasParent)
true -> parent!!.y1
else -> field
和
var y1: Double = 0.0
get() = parent?.y1!!
(hasParent
只是一个查看parent
是否为空的getter)
这两个在语义上是否相同,或者它们实际上是不同的表达方式,意味着不同的事物?如果它们在语义上的意思相同,那么出于某种原因,第一个是否优于第二个?
【问题讨论】:
第二种形式与第一种不同,不正确。如果parent
为空,您将得到NullPointerException
。 parent?.y1 ?: field
相当于第一种形式。
您能否将其移至答案以便我接受?
【参考方案1】:
在这种情况下,您不需要hasParent
。适用的形式是这样的:\
var y1: Double = 0.0
get() = parent?.y1 ?: field
您的第二个 getter 的问题是,无论如何它都会尝试返回 parent.y1
,如果它不存在,它将抛出 NullPointerException
。
如果您使用 IDEA,您会收到此类问题的警告,因此很容易解决,但您需要注意来自 Java 代码的所谓平台类型:
val queue: Queue<String> = LinkedList()
queue.peek().toInt()
这里编译器不会为.toInt()
抱怨,尽管可以从Queue
获得空值。我已经写过这个here。
【讨论】:
【参考方案2】:请注意,jingx 和 Adam Arold 的回答对当前情况很好,但如果 y1
的类型可以为空,则它不等于您的第一个 sn-p:如果 parent
不为空,而是 @ 987654323@ 是,那么你的代码给出null
和parent?.y1 ?: field
给出field
。
如果您需要第一种行为,我会说实际的首选形式是
if (parent != null) parent.y1 else field // if parent is val without a custom getter
parent.let if (it != null) it.y1 else field // otherwise
使用hasParent
对编译器隐藏了您实际检查是否为空并且不需要!!
。
【讨论】:
以上是关于猫王运算符与非空断言:这些语句之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章
18 19 20 py if语句 比较运算符 断言assertions
javascript 中是不是有空合并 (Elvis) 运算符或安全导航运算符?