Wie komme ich bei Scala mit Typ-Löschen zurecht? Oder, warum kann ich den Typparameter meiner Sammlungen nicht erhalten?
Es ist eine traurige Tatsache des Lebens auf der Scala, wenn Sie instanziieren eine List[Int] können Sie überprüfen, ob Ihre Instanz ist eine Liste, und Sie können überprüfen, dass jedes einzelne element, es ist ein Int, aber nicht, dass es eine List[Int], wie man leicht verifiziert:
scala> List(1,2,3) match {
| case l : List[String] => println("A list of strings?!")
| case _ => println("Ok")
| }
warning: there were unchecked warnings; re-run with -unchecked for details
A list of strings?!
Den -nicht angekreuzte option legt die Schuld direkt auf type-erasure:
scala> List(1,2,3) match {
| case l : List[String] => println("A list of strings?!")
| case _ => println("Ok")
| }
<console>:6: warning: non variable type-argument String in type pattern is unchecked since it is eliminated by erasure
case l : List[String] => println("A list of strings?!")
^
A list of strings?!
Warum ist das so, und wie bekomme ich es?
InformationsquelleAutor der Frage Daniel C. Sobral | 2009-07-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Scala definiert wurde, mit Type Erasure, weil die Java Virtual Machine (JVM), im Gegensatz zu Java, nicht bekommen Generika. Dies bedeutet, dass zur Laufzeit immer nur die Klasse existiert, nicht sein Typ-Parameter. In dem Beispiel, JVM weiß, es ist der Umgang mit einem
scala.collection.immutable.List
aber nicht, dass diese Liste parametrisiert ist mitInt
.Glücklicherweise gibt es eine Funktion in Scala, mit der Sie umgehen können. Es ist die Manifest. Ein Manifest ist Klasse, deren Instanzen sind Objekte, die Typen. Da diese Instanzen sind Objekte, die Sie übergeben können, Sie, speichern Sie, und in der Regel rufen Methoden auf. Mit der Unterstützung von impliziten Parameter, wird es ein sehr mächtiges Werkzeug. Nehmen Sie das folgende Beispiel, zum Beispiel:
Beim speichern ein element, speichern wir ein "Manifest" von ihm auch. Ein Manifest ist eine Klasse, deren Instanzen repräsentieren Scala-Typen. Diese Objekte haben mehr Informationen, als die JVM, die es uns ermöglichen, zu testen, die voll parametrisierte Typ.
Beachten Sie jedoch, dass eine
Manifest
ist immer noch ein sich entwickelndes feature. Als ein Beispiel für die Einschränkungen, die Sie derzeit nicht wissen, etwas über die Varianz, und meint alles ist co-Variante. Ich erwarte, dass es mehr stabil und solide, sobald die Scala reflection-Bibliothek, die derzeit in der Entwicklung befindet, beendet wird.InformationsquelleAutor der Antwort Daniel C. Sobral
Können Sie dies mit TypeTags (wie Daniel schon erwähnt, aber ich werde einfach spell it out explizit):
Können Sie auch dies tun, indem Sie ClassTags (welche speichert Sie vom müssen davon abhängen, scala-spiegeln):
ClassTags kann verwendet werden, solange Sie nicht erwarten, dass die Typ-parameter
A
um sich einen generischen Typ.Leider ist es etwas Ausführlicher, und Sie müssen das @ - deaktiviert Anmerkung zu unterdrücken, um eine compiler-Warnung. Der TypeTag eingearbeitet werden können in die pattern-match-automatisch durch den compiler in die Zukunft: https://issues.scala-lang.org/browse/SI-6517
InformationsquelleAutor der Antwort tksfz
Können Sie die
Typeable
Typ-Klasse von formlose das Ergebnis erhalten Sie nach,Probe REPL-Sitzung,
Den
cast
Vorgang wird als präzise wrt Löschung wie möglich, da die in-scopeTypeable
Instanzen zur Verfügung.InformationsquelleAutor der Antwort Miles Sabin
Habe ich eine relativ einfache Lösung, das würde genügen, in der limited-use-Situationen, die im wesentlichen der Verpackung parametrisierte Typen, die würden leiden unter dem Typ erasure problem in wrapper-Klassen, die verwendet werden können in einem match-statement.
Dieser hat die erwartete Ausgabe und die Grenzen der Inhalt in unserem Fall die Klasse, um den gewünschten Typ, String-Listen.
Mehr details hier: http://www.scalafied.com/?p=60
InformationsquelleAutor der Antwort thricejamie
Es ist ein Weg zur überwindung der type erasure Problem in Scala. In Die überwindung Type-Erasure in passenden 1 und Die überwindung Type-Erasure in Passenden 2 (Varianz) sind eine Erklärung, wie man code mit einigen Helfern, die zum wickeln des Typen, einschließlich Varianz, die für das matching.
InformationsquelleAutor der Antwort
Fand ich einen etwas besseren workaround für diese Einschränkung der ansonsten wunderbare Sprache.
In Scala die Ausgabe von type erasure tritt nicht mit arrays. Ich denke, es ist einfacher zu zeigen dies mit einem Beispiel.
Lassen Sie uns sagen, wir haben eine Liste von
(Int, String)
dann die folgende gibt eine Art Löschung AchtungUm dies zu umgehen, erstellen Sie zuerst eine Fall-Klasse:
dann in den pattern-matching-tun Sie etwas wie:
scheint zu funktionieren perfekt.
Dies erfordert kleine änderungen im code, um die Arbeit mit arrays anstelle von Listen, sollte aber kein großes problem.
Beachten Sie, dass die Verwendung
case a:Array[(Int, String)]
wird immer noch ein type-erasure Warnung, so ist es notwendig, einen neuen container-Klasse (in diesem BeispielIntString
).InformationsquelleAutor der Antwort Jus12
Da Java nicht weiß, dem eigentlichen element-Typ, ich fand es besonders nützlich, um Sie nur
List[_]
. Dann ist die Warnung Weg geht und der code beschreibt die Wirklichkeit - es ist eine Liste von etwas unbekannten.InformationsquelleAutor der Antwort rained_in
Frage ich mich, ob dies eine geeignete Problemumgehung:
Es entspricht nicht der "leere Liste", aber es gibt einen compile-Fehler, keine Warnung!
Diese auf der anderen Seite scheint zu funktionieren....
Ist es nicht irgendwie auch besser, oder übersehe ich den Punkt hier?
InformationsquelleAutor der Antwort agilesteel
Nicht eine Lösung, sondern eine Weise zu Leben, ohne kehren es unter den Teppich zusammen:
Hinzufügen der
@unchecked
annotation. Siehe hier - http://www.scala-lang.org/api/current/index.html#scala.uncheckedInformationsquelleAutor der Antwort matanster
Wollte ich hinzufügen, dass eine Antwort, die vergröbert das problem: Wie bekomme eine String-Darstellung des Typs von meiner Liste zur Laufzeit
InformationsquelleAutor der Antwort Steve Robinson
Mit pattern-match-guard
InformationsquelleAutor der Antwort Huangmao Quan