2012-03-16 15 views
10

Esperaría que esto me diera un error de tipo ya que (String, String) en el caso else no es Pair.¿Por qué esto no da un tipo de error?

case class Pair(x: String, y: String) 

val value = Console.readLine.toBoolean 

val Pair(x, y) = 
    if (value) Pair("foo", "bar") 
    else false 

En cambio, si ingreso falso, aparece el siguiente error en el tiempo de ejecución.

scala.MatchError: (foo,bar) (of class scala.Tuple2) 

supongo que la deconstrucción es sólo azúcar para asignar el resultado a una variable de tipo Any y luego a juego en él, pero parece lamentable que Scala permite esta mosca.

Respuesta

7

Si compila este código con scalac -print verá, qué sucede. Como supusiste correctamente, es solo azúcar sintáctico para una coincidencia de patrones. En realidad, su clase de casos amplía Product, que también es una superclase de Tuple2 y es la que su código compila. Su valor se asigna a una variable de tipo de producto:

val temp6: Product = if (value) 
     new Main$Pair("foo", "bar") 
    else 
     new Tuple2("foo", "bar"); 

Y luego se aplica una coincidencia de patrones a ella:

if (temp6.$isInstanceOf[Main$Pair]()) 
{ 
    <synthetic> val temp7: Main$Pair = temp6.$asInstanceOf[Main$Pair](); 
    new Tuple2(temp7.x(), temp7.y()) 
} 
else 
    throw new MatchError(temp6) 

Pero nontheless esto no debería compilar en mi humilde opinión. Debe publicar esto en la lista de correo de scala.

+0

Necesito recordar este comando ('scalac')! – schmmd

+0

Es bueno saberlo, pero no creo que el supertipo común de 'Producto' sea el que compila. Cambié mi ejemplo para mostrar esto, ¡aunque ambos todavía tienen un súper tipo común de 'Any'! – schmmd

Cuestiones relacionadas