2012-09-29 14 views
6

Sto imparando il concetto di manifest di Scala e ho una comprensione di base su come usarlo in alcuni casi semplici. Che cosa mi lascia perplesso è: OptNanifest e NoManifest? Non l'ho mai visto poi usato. Qualcuno può dare un esempio dove sono necessari/utili?A cosa servono la versione di Opt di Opt e di NoManifest?

(vedo che Scala 2.10 sostituisce il concetto di Manifest s con TypeTags ma fino a 2.10 è definitiva dobbiamo usare Manifest s.)

risposta

6

Supponiamo di avere la seguente classe caso e il tipo di alias:

scala> case class Foo[A](a: A) 
defined class Foo 

scala> type F = Foo[_] 
defined type alias F 

ora possiamo (non molto utile) fare una lista delle cose di tipo F:

scala> val foos: List[F] = List(Foo(1), Foo("a"), Foo('a)) 
foos: List[F] = List(Foo(1), Foo(a), Foo('a)) 

E possiamo trasformare questo in un array:

scala> foos.toArray 
res0: Array[F] = Array(Foo(1), Foo(a), Foo('a)) 

Quindi chiaramente il compilatore è in grado di trovare il manifesto di cui ha bisogno come un argomento implicito del metodo toArray su List. Ma se chiediamo una pianura vecchio Manifest per F, otteniamo un errore:

scala> manifest[F] 
<console>:11: error: overloaded method value classType with alternatives: 
    (prefix: scala.reflect.Manifest[_],clazz: Class[_],args: scala.reflect.Manifest[_]*)scala.reflect.Manifest[F] <and> 
    (clazz: Class[F],arg1: scala.reflect.Manifest[_],args: scala.reflect.Manifest[_]*)scala.reflect.Manifest[F] <and> 
    (clazz: Class[_])scala.reflect.Manifest[F] 
cannot be applied to (java.lang.Class[Foo[_$1]], scala.reflect.Manifest[_$1]) 
       manifest[F] 

Quindi è chiaro che il compilatore sta avendo problemi con l'uso si manifesta per rappresentare il carattere jolly nel nostro tipo di alias.

Il motivo toArray funziona è che si aspetta uno ClassManifest, non solo uno Manifest. E infatti possiamo ottenere un ClassManifest per per il ClassManifest, precisamente per OptManifest per rappresentare i suoi argomenti tipo, a differenza di Manifest, i cui argomenti tipo sono solo altre cose di tipo Manifest.

scala> classManifest[F] 
res2: ClassManifest[F] = Foo[<?>] 

Questo <?> è la rappresentazione di stringa di NoManifest. Qui svolge il ruolo di None, consentendo al compilatore di rappresentare le informazioni di classe sul tipo F (che è tutto ciò di cui abbiamo bisogno per creare un array, fortunatamente), senza dire nulla sugli argomenti di tipo di F oltre "no, I can ' t modello quello ".

Problemi correlati