【问题标题】: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 为空,您将得到NullPointerExceptionparent?.y1 ?: field 相当于第一种形式。
  • 您能否将其移至答案以便我接受?

标签: nullpointerexception kotlin type-safety kotlin-null-safety


【解决方案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@ 是,那么你的代码给出nullparent?.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 对编译器隐藏了您实际检查是否为空并且不需要!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-17
      • 2018-09-26
      • 2010-12-31
      • 2013-11-04
      • 2013-12-18
      • 2015-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多