在 Scala 中将 null 转换为 case class 的实例

Casting null to an instance of a case class in Scala

我有一段代码依赖于特定案例 class 的任意元素的存在,以便对 class 的字段进行操作。有some options out there, and even though pretty much every Scala blog recommends not using null ever, it seems like not a terrible idea in type level programming (e.g. this answer: )。但是,此代码直接将 null 强制转换为特定情况 class 不起作用并且不会引发错误,我对原因很感兴趣。

trait V {}
case class W(x: Int) extends V

val y = null.asInstanceOf[W]

y match {
  case w:W => println("null cast to W is a W")
  case _ => println("null cast to W is NOT a W")
}

// prints "null cast to W is NOT a W"

y match {
  case v:V => println("null cast to W is a V")
  case _ => println("null cast to W is NOT a V")
}

// prints "null cast to W is NOT a V"

val z = W(1)

z match {
  case w:W => println("instantiated W is a W")
  case _ =>  println("instantiated W is NOT a W")
  }

// prints "instantiated W is a W"

z match {
  case v:V =>  println("instantiated W is a V")
  case _ =>  println("instantiated W is NOT a V")
}

// prints "instantiated W is a V"

转换会更改编译时类型,而不是运行时类型。模式匹配检查运行时类型。事实上,case class 模式匹配甚至对 null 有显式检查;请参阅 Why is there a `null` check in the implementation of the `unapply` method for case classes?(尽管该检查不会影响您的情况,因为您使用的是类型模式)。

此外,即使不是模式匹配问题,您也无法 "operate on the class's fields" 得到 NullPointerException。

因为 Type Patterns 是这样定义的:

  • A reference to a class C, p.C, or T#C. This type pattern matches any non-null instance of the given class.

因此:null 是类型 W 的完全有效值;但它不会与模式 w: W.

匹配

而不匹配的主要原因恰恰是

I have a piece of code that relies on the existence of an arbitrary element of a certain case class in order to operate on the class's fields.

所以当你匹配 w: W 时你想知道它的字段和方法是否可用。但是 null 他们不是。