2011-03-15 13 views
7

Me pregunto ¿cuál es la razón de la (implicit ev: Null <:< A1) aquí:¿Por qué el método Opción o No tiene este argumento implícito superfluo?

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

No sería

def orNull[A]: A = this getOrElse null 

ser suficiente teniendo en cuenta que ni siquiera parece trabajar con tipos de valor como

Option(1).orNull 

pero

Option(1).getOrElse(null) 

hace?

Option 's source code

+2

'La opción (1) .getOrElse (null)' "funciona", pero el tipo general es Cualquiera, que no es un tipo muy útil. –

Respuesta

10

No todos los tipos de Scala puede ser nulo. En particular, Any tiene dos hijos, AnyRef y AnyVal. AnyRef puede manejar tipos nulos. Los tipos AnyVal pueden ser primitivos en la JVM y, por lo tanto, no pueden ser nulos. Lo implícito es una verificación de tipo demorada que permite que Option [String] use o No, pero no Opción [Int].

Nota: Esta dicotomía de que el objeto interno/objeto no encasillado/primitivo tiene manifestaciones muy extrañas en Scala, como null.asInstanceOf [Int] == ​​0 // true.

+1

Incluso esto funciona: 'null.asInstanceOf [Nothing] // NPE' – soc

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 
             ^

Así, null no es un tipo aceptable para todos A, sólo para los anulables. Las subclases de AnyVal son ejemplos típicos de tipos que no admiten nulos. En ausencia de ese parámetro, no es posible escribir este método.

Cuestiones relacionadas