2010-01-08 10 views
6

No entiendo por qué el siguiente caso no coincide. Null debe ser una instancia de Any, pero no coincide. ¿Alguien puede explicar lo que está pasando?coincide con la tupla con nulo

val x = (2, null) 
x match { 
    case (i:Int, v:Any) => println("got tuple %s: %s".format(i, v)) 
    case _ => println("catch all") 
} 

prints catch all 

Gracias.

Respuesta

9

Esto es exactamente como se especifica.

Type patterns consist of types, type variables, and wildcards. 
A type pattern T is of one of the following forms: 

* A reference to a class C, p.C, or T#C. 
This type pattern matches any non-null instance of the given class. 

Es interesante que se haya atribuido tanta relevancia al hecho de que null sea miembro de Any. Es un miembro de todos los tipos, excepto AnyVal y Nothing.

+0

Supongo que una de las razones de esta elección es que coincide con el comportamiento del bytecode "instanceof" en la JVM. –

+0

Eso, y dejar que la nulidad desapareciera por completo. ¡Debes tener una tolerancia nula y obscena para buscar motivaciones! – extempore

+0

"Tolerancia nula obscena" o no, existe un argumento de que el significado más natural y sencillo para un patrón de tipo "x: T" es hacer coincidir cualquier miembro de tipo T. Por ejemplo, evitaría irregularidades como "val x: Any = null "- bien, pero" val (x: Any, y: Any) = (null, null) "- MatchError. Eso "mata por completo" también. No estoy diciendo que Scala tomó la decisión equivocada, ni que sea particularmente importante dado que la idiomática Scala evita el uso de nulo. –

1

Estoy adivinando aquí ya que no soy un experto en scala, pero de acuerdo con documentation para la clase Any en scala, estoy pensando que dado que null no es un objeto, no deriva de Any y como tal no coincide con el primer caso enumerado.

Agregando el siguiente ejemplo de código. Imprime "algo más" cuando se ejecuta.

val x = (2, null) 
x match { 
    case (i:Int, v:Any) => println("got tuple %s: %s".format(i, v)) 
    case (i:Int, null) => println("something else %s".format(i)) 
    case _ => println("catch all") 
} 

Después de más investigación que parece nula debe coincidir con algún sentido del documentation dice que se extienda AnyRef que se extiende Cualquier.

EDITAR: Como todos los demás han dicho. El primer caso no coincide nulo a propósito. Está especificado en la documentación.

+0

'null' es la instancia única de la clase' Null'. –

+0

Eso tiene sentido. La documentación para null (http://www.scala-lang.org/docu/files/api/scala/Null.html) dice que se extiende AnyRef que se extiende Any, por lo que parece que debe coincidir con el caso (i: Int, v: Cualquiera). –

3

Eso es como se especifica (Scala Referencia 2.7, sección 8.2):

Una referencia a una clase C, p.C, o T # C. Este tipo de patrón coincide con cualquier instancia no nula de la clase dada. Tenga en cuenta que el prefijo de la clase, si se da , es relevante para que determina instancias de clase. Para la instancia , el patrón p.C coincide solo con instancias de clases C que fueron creadas con la ruta p como prefijo.

6

Ha intentado el marcador de posición para v nada?

val x = (2, null) 
x match { 
    case (i:Int, v) => println("got tuple %s: %s".format(i, v)) 
    case _ => println("catch all") 
} 
Cuestiones relacionadas