在 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
他们不是。
我有一段代码依赖于特定案例 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
, orT#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
他们不是。