2011-03-15 15 views
7

我不知道什么是这里的(implicit ev: Null <:< A1)的原因:为什么Option的orNull方法有这种多余的隐含参数?

sealed abstract class Option[+A] extends Product with Serializable { 
    def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null 
    ... 
} 

岂不

def orNull[A]: A = this getOrElse null 

足够考虑,它甚至不似乎与值类型的工作像

Option(1).orNull 

但是

Option(1).getOrElse(null) 

呢?

Optionsource code

+2

'Option(1).getOrElse(null)'“有效”,但总体类型为Any,这不是一个非常有用的类型。 – 2011-03-15 18:09:23

回答

10

并非所有的斯卡拉类型可以为空。特别是,Any有两个孩子,AnyRef和AnyVal。 AnyRef可以处理空类型。 AnyVal类型可以是JVM上的基元,因此不能为null。隐含的是延迟类型检查,允许Option [String]使用orNull而不是Option [Int]。

注意:Int被盒装/拆箱的对象/原语的这种二分法在Scala中有非常奇怪的表现形式,例如null.asInstanceOf [Int] == 0 // true。

+1

即使这样做:'null.asInstanceOf [Nothing] // NPE' – soc 2011-03-15 17:40:28

5
scala> abstract class Op[A] { 
    | def getOrElse(b: A): A 
    | def orNull[A]: A = this getOrElse null 
    | } 
<console>:14: error: type mismatch; 
found : Null(null) 
required: A 
     def orNull[A]: A = this getOrElse null 
             ^

所以,null并不适用于所有A可接受的类型,只为可空的。 AnyVal的子类是不可空类型的典型例子。如果没有该参数,则不可能编写此方法。