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 ".