为什么我可以为选项分配null?

时间:2013-08-24 05:29:51

标签: scala

以下是Scala中的有效声明:

scala> var x: Option[Int] = Some(3)
x: Option[Int] = Some(3)

scala> var x: Option[Int] = None
x: Option[Int] = None

以下内容无效:

scala> var x: Option[Int] = 3
<console>:7: error: type mismatch;
 found   : Int(3)
 required: Option[Int]
       var x: Option[Int] = 3

到目前为止,这些例子对我有意义; Option [T]类型的值可以是Some [T]或None类型,因此编译器会阻止您分配既不是类型的值。

但是,Scala编译器似乎接受了这个:

scala> val x: Option[Int] = null
x: Option[Int] = null

如果我然后尝试对选项进行模式匹配(例如如下),我会得到我没想到的失败 - 为什么编译器不会通过拒绝null的赋值来保护我? / p>

x match {
  case Some(y) => println("Number: ", y)
  case None => println("No number")
}

2 个答案:

答案 0 :(得分:6)

如果查看Scala class hierarchy,您会看到从AnyRef派生的所有类都是Null的超类,并且任何此类超类都可以赋值{{ 1}}。由于null是此类,因此您可以为其指定Option

请注意,NullSome(即None.type对象的单例类型)都是None的超类,因此Null是任何一个的有效值。

您无法将null分配给3,因为Option不是3子类的值(显然)。

答案 1 :(得分:0)

你可能要问的问题的答案是这样的:

惯用语Scala永远不会使用null。空引用纯粹是为了与Java和其他JVM语言的互操作性。如果您在Scala代码中看到null,它应立即引起审查。您永远不会错误地使用null,因此不需要编译器警告。正如Daniel Sobral的回答和评论中所述,编译器无法提供针对null的保护。