以下是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")
}
答案 0 :(得分:6)
如果查看Scala class hierarchy,您会看到从AnyRef
派生的所有类都是Null
的超类,并且任何此类超类都可以赋值{{ 1}}。由于null
是此类,因此您可以为其指定Option
。
请注意,Null
和Some
(即None.type
对象的单例类型)都是None
的超类,因此Null
是任何一个的有效值。
您无法将null
分配给3
,因为Option
不是3
子类的值(显然)。
答案 1 :(得分:0)
你可能要问的问题的答案是这样的:
惯用语Scala永远不会使用null
。空引用纯粹是为了与Java和其他JVM语言的互操作性。如果您在Scala代码中看到null
,它应立即引起审查。您永远不会错误地使用null
,因此不需要编译器警告。正如Daniel Sobral的回答和评论中所述,编译器无法提供针对null
的保护。