【问题标题】:Why is there a `null` check in the implementation of the `unapply` method for case classes?为什么在案例类的`unapply`方法的实现中有`null`检查?
【发布时间】:2019-10-13 08:31:06
【问题描述】:

我正在努力用我自己的实现替换案例类的伴随对象上的unapply 方法。在调查了与实现unapply 相关的许多不同切线之后,似乎在大多数情况下都存在null 保护,无论是在编译器生成的代码中,还是在显式重新定义的实现中。编译器为unapply 生成的代码与此类似(其中一些使用eq 而不是ne):

def unapply(location: Location): Option[(Double, Double)] =
  if (location ne null)
    Some((location.longitude, location.latitude))
  else
    None

鉴于在纯(即惯用的)Scala 代码中绝对不应该使用null,为什么要执行null 检查?它是否与 Java 互操作(因为 Java 仍然沉迷于利用 null)泄漏到 unapply 方法有关?如果我删除检查,因为我已经消除了 unapply 方法被传递到的案例类实例可能为 null 或无效的可能性,我将遭受什么(如果有的话)不良后果? IOW,用这个替换上述实现有什么害处?

def unapply(location: Location): Option[(Double, Double)] =
  Some((location.longitude, location.latitude))

【问题讨论】:

  • this 可能会部分回答您的问题
  • 我通读了那个答案,找不到任何解决空检查的内容,除了他的回答还包括空检查。发布的原始问题离我的具体问题太远了,我发现它对明确回答我上面的问题很有用。
  • 如果你能保证Location永远不会是null,那就没有坏处。强调“如果”。
  • @Lasf 知道了。鉴于这是我在过去 +8 年中最终使用和编写的所有 Scala 代码中所做的假设(这显然是更大的 Scala 社区的默认假设),这似乎是一个微不足道的保证。责任在于执行 Java 互操作以包含和限制可能感染 Scala 代码的任何类型的空“泄漏”,包括获取我的 Scala 代码,特别是包括点击我的unapply 方法。

标签: scala pattern-matching case-class unapply compiler-generated


【解决方案1】:

否则,这会产生非常令人惊讶的行为:

nullableJavaMethod() match {
  case Location(lat, long) => "Handle location here!"
  case null => "Handle null here!"
}

您可能更喜欢另一种处理 null 的方法,但这并不意味着如果有人更喜欢这种方法,您应该使用 NPE 进行上述崩溃。请注意,这是特定于unapply,因为其他方法不会遇到上述问题。

【讨论】:

  • 这个答案不起作用,因为我的问题不是我的偏好。我在问为什么只有 Scala 代码中存在空保护,在这种代码中,消除所有对空的引用是惯用的,包括特别是空保护。通过将上面的代码更改为Option(nullableJavaMethod()) match { case Some(Location(lat, long)) => "Handle location here!"; case None => "Handle null here!"},您的上面的代码被简单地更改为惯用的 Scala 代码
  • @chaotic3quilibrium 尽管如此,大多数人——尤其是初学者——会期望我提供的代码能够工作,如果它失败了会非常惊讶。我们不应该为初学者设置陷阱,尤其是运行时陷阱。此外,我能想到在 Scala 中使用null 的几个原因(很少见),例如performanceoptional implicits
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 2015-11-09
  • 2013-09-26
  • 2019-06-04
  • 2020-03-07
  • 2013-05-25
相关资源
最近更新 更多