2009-09-08 12 views
9

Al escribir el siguiente código en ScalaError de análisis de tuplas anidadas en Scala

var m = Map((0,1) -> "a") 
m += ((0,2), "b") // compilation error 

estoy recibiendo el error

 
type mismatch; 
found : Int(0) 
required: (Int, Int) 

Sin embargo, el cambio de la sintaxis de la tupla de (X,Y) a (X -> Y) obras

var m = Map((0,1) -> 'a) 
m += ((0,2) -> 'b) // compiles file 

Aunque

((0,1).getClass == (0 -> 1).getClass) // is true 
(0,1).isInstanceOf[Tuple2[_,_]] && (0 -> 1).isInstanceOf[Tuple2[_,_]] // both true 

¿Por qué es eso? ¿Qué cree Scala que es mi tupla anidada?

+0

I * * siempre hacen el mismo error –

Respuesta

10

La razón es bastante simple (creo) y tiene que ver con el hecho de que (en el rasgo Map):

m += (a -> b) 

es la abreviatura de:

m = m.+(t2) //where t2 is of type Tuple2[A,B] 

Obviamente, si se utiliza una coma en el primer ejemplo, Scala interpretará esto como una llamada al método:

m = m.+(a, b) 

Este método no existe en el rasgo Map. Las reglas de invocación de métodos significan que a -> b se evalúa primero (al Tuple2) y de ahí que se llame al método correcto. Nota: Usando un par extra de paréntesis, funciona muy bien:

m += ((a,b)) //works just fine but less readable 
+0

realidad estaba bastante seguro de que Obj Op Pred es equivalente a Pred.Op ((Pred)) ya. ¿Hay algún uso (en la biblioteca estándar, o Ascensor) para llamar a una función con dos argumentos como operador? (Un ejemplo que tiene sentido, por supuesto, siempre puedes hacer "actualización de matriz (x, y)" pero simplemente se ve extraño. –

+0

Estoy de acuerdo contigo Elazar. Creo que el compilador debería tener un poco más de sentido aquí –

0

Oxbow es correcta. Se puede utilizar otro paréntesis para eliminar la ambigüedad, sin embargo:

m += (((0,2), "b")) 
+0

Creo Señalé que el paréntesis adicional resolvió el problema –