2012-03-16 9 views
10

Mi aspetto che questo mi dia un errore di tipo dal (String, String) nel caso else non è Pair.Perché questo non dà un errore di tipo?

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

val value = Console.readLine.toBoolean 

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

Invece, se entro falso, ottengo il seguente errore in fase di esecuzione.

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

Suppongo che la decostruzione è solo zucchero per assegnare il risultato a una variabile di tipo Any e poi di corrispondenza su di esso, ma sembra un peccato che Scala lascia questa mosca.

risposta

7

Se si compila questo codice con scalac -print si vede, cosa succede. Come hai giustamente supposto, è solo zucchero sintattico per un pattern matching. In realtà la tua classe case estende Product, che è anche una superclasse di Tuple2 e che è il tuo codice compilato. Il tuo valore viene assegnato a una variabile di tipo di prodotto:

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

E poi viene applicato un pattern matching ad esso:

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) 

Ma modernista questo non dovrebbe compilare imho. Dovresti postare questo alla mailing list di scala.

+0

Ho bisogno di ricordare questo comando ('scalac')! – schmmd

+0

È bello saperlo, ma non penso che il supertipo comune di "Prodotto" sia il motivo per cui viene compilato. Ho cambiato il mio esempio per mostrarlo, anche se entrambi hanno ancora un super tipo comune di 'Any'! – schmmd

Problemi correlati