Il compilatore conosce più informazioni sui tipi che il runtime JVM può rappresentare facilmente. Un Manifest è un modo per il compilatore di inviare un messaggio interdimensionale al codice in fase di esecuzione sulle informazioni sul tipo che sono state perse.
Questo è simile a come i Kleptoniani hanno lasciato messaggi codificati nei reperti fossili e nel DNA "spazzatura" degli umani. A causa delle limitazioni della velocità della luce e dei campi di risonanza gravitazionale, non sono in grado di comunicare direttamente. Ma, se sai sintonizzarti sul loro segnale, puoi trarre beneficio da modi che non riesci a immaginare, dal decidere cosa mangiare a pranzo o quale numero di lotto giocare.
Non è chiaro se un Manifest trarrebbe beneficio dagli errori che stai vedendo senza conoscere maggiori dettagli.
Un uso comune di Manifests è far sì che il codice si comporti in modo diverso in base al tipo statico di una raccolta. Ad esempio, cosa succede se si desidera trattare un Elenco [String] in modo diverso dagli altri tipi di un Elenco:
def foo[T](x: List[T])(implicit m: Manifest[T]) = {
if (m <:< manifest[String])
println("Hey, this list is full of strings")
else
println("Non-stringy list")
}
foo(List("one", "two")) // Hey, this list is full of strings
foo(List(1, 2)) // Non-stringy list
foo(List("one", 2)) // Non-stringy list
Una soluzione basata sulla riflessione probabilmente implicherebbe l'ispezione di ciascun elemento dell'elenco.
Un limite di contesto sembra più adatto all'uso delle classi di tipi in scala, ed è ben spiegato qui da Debasish Ghosh:
http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-i.html
I limiti di contesto possono anche solo rendere più leggibili le firme del metodo. Ad esempio, la funzione sopra potrebbe essere riscritta usando i limiti di contesto in questo modo:
def foo[T: Manifest](x: List[T]) = {
if (manifest[T] <:< manifest[String])
println("Hey, this list is full of strings")
else
println("Non-stringy list")
}