Sto cercando di capire cosa Scala fa con Case Classes che li rende in qualche modo immuni agli avvisi di cancellazione del tipo.Scala: Case class inapplicata rispetto a un'implementazione manuale e cancellazione di tipo
Diciamo che abbiamo la seguente struttura di classe semplice. E 'fondamentalmente un Either
:
abstract class BlackOrWhite[A, B]
case class Black[A,B](val left: A) extends BlackOrWhite[A,B]
case class White[A,B](val right: B) extends BlackOrWhite[A,B]
E si sta cercando di usare in questo modo:
object Main extends App {
def echo[A,B] (input: BlackOrWhite[A,B]) = input match {
case Black(left) => println("Black: " + left)
case White(right) => println("White: " + right)
}
echo(Black[String, Int]("String!"))
echo(White[String, Int](1234))
}
Tutto compila e funziona senza problemi. Tuttavia, quando provo a implementare il metodo unapply
da solo, il compilatore genera un avviso. Ho usato la seguente struttura di classe con la stessa Main
classe superiore:
abstract class BlackOrWhite[A, B]
case class Black[A,B](val left: A) extends BlackOrWhite[A,B]
object White {
def apply[A,B](right: B): White[A,B] = new White[A,B](right)
def unapply[B](value: White[_,B]): Option[B] = Some(value.right)
}
class White[A,B](val right: B) extends BlackOrWhite[A,B]
Compilare che con gli -unchecked
questioni di bandiera il seguente avviso:
[info] Compiling 1 Scala source to target/scala-2.9.1.final/classes...
[warn] src/main/scala/Test.scala:41: non variable type-argument B in type pattern main.scala.White[_, B] is unchecked since it is eliminated by erasure
[warn] case White(right) => println("White: " + right)
[warn] ^
[warn] one warning found
[info] Running main.scala.Main
Ora, capisco la cancellazione di tipo e ho cercato di aggirare l'avviso con Manifests
(fino ad ora inutilmente), ma qual è la differenza tra le due implementazioni? Le classi del caso fanno qualcosa che devo aggiungere? Può essere aggirato con Manifests
?
Ho anche provato a fare funzionare l'implementazione caso di classe attraverso il compilatore Scala con la bandiera -Xprint:typer
acceso, ma il metodo unapply
sembra più o meno come mi aspettavo:
case <synthetic> def unapply[A >: Nothing <: Any, B >: Nothing <: Any](x$0: $iw.$iw.White[A,B]): Option[B] = if (x$0.==(null))
scala.this.None
else
scala.Some.apply[B](x$0.right);
Grazie in anticipo
Sei utilizzando l'ultima versione di Scala? Non riesco a riprodurre il problema e questa domanda correlata di alcuni mesi fa ha determinato un problema simile al tuo come un bug del compilatore. Consulta http://stackoverflow.com/questions/7008428/difference tra-home-made-extractor-and-case-extractor – Destin
Sto usando 2.9.1.final (Su Xubuntu 11.10, se è importante) – Nycto