2010-12-13 3 views
5

cosa c'è di sbagliato in questo pezzo di codice?scala entrambi i modelli corrispondono a

(Left("aoeu")) match{case Right(x) => ; case Left(x) => }
<console>:6: error: constructor cannot be instantiated to expected type; 
found : Right[A,B] 
required: Left[java.lang.String,Nothing]  

perché il matcher modello semplicemente non saltare la Destra e la Sinistra esaminare?

+0

Uhm, il compilatore ti sta dicendo che parte del tuo codice non è raggiungibile. Questa è una buona cosa, sì? –

risposta

11

La digitazione implicita è che Left("aoeu") è un Left[String,Nothing]. È necessario digitarlo esplicitamente.

(Left("aoeu"): Either[String,String]) match{case Right(x) => ; case Left(x) => } 

Sembra che i modelli che corrispondono ai candidati debbano sempre essere di un tipo corrispondente al valore corrispondente.

scala> case class X(a: String) 
defined class X 

scala> case class Y(a: String) 
defined class Y 

scala> X("hi") match { 
    | case Y("hi") => ; 
    | case X("hi") => ; 
    | } 
<console>:11: error: constructor cannot be instantiated to expected type; 
found : Y 
required: X 
     case Y("hi") => ; 
      ^

Perché si comporta in questo modo? Sospetto che non ci siano buoni motivi per tentare di abbinare su un tipo incompatibile. Il tentativo di farlo è un segnale che lo sviluppatore non sta scrivendo ciò che realmente intendono. L'errore del compilatore aiuta a prevenire i bug.

+4

Penso che tu abbia sottovalutato il punto chiave: il compilatore stava correttamente indicando che una parte del codice era irraggiungibile. Sì, puoi sconfiggere quell'errore, ma non dovresti. – Malvolio

3
scala> val left: Either[String, String] = Left("foo") 
left: Either[String,String] = Left(foo) 

scala> left match { 
    | case Right(x) => "right " + x 
    | case Left(x) => "left " + x } 
res3: java.lang.String = left foo