Die json API verwendet ausgiebig implizite Parameter, was ein Merkmal von Scala ist, wo Sie eine "implizite" Parameterliste bereitstellen können und wenn Sie diese Parameter nicht angeben, wird der Compiler versuchen, ein Objekt im aktuellen Bereich zu finden markiert als implizit und entspricht dieser Signatur.
So würde, wenn Sie zum Beispiel schreiben:
implicit val s = "my implicit string"
def magicPrint(implicit message: String) { println(message) }
// and then call it
magicPrint
Der Compiler s für den Parameter Nachricht wählen würde, da sie in ihrem Umfang und hat den richtigen Typ (String
), so dass nach der impliziten Auflösung der letzten Zeile Code aussehen würde eigentlich eher wie dieses
magicPrint(s)
Das Format/Writer vom Compiler ausgewählt wird, bei der Kompilierung mit einem impliziten Parameter. Wenn Sie sich die Signatur der Methode ansehen, toJson[A](item: A)(implicit writes: Writes[A])
, dauert es eine implizite Writes[A]
, die in Ihrem Fall eine Writes[List[Animal]]
ist, da List[Animal]
der Typ Ihrer Liste l
ist. Play enthält einen Standard hat einen Schreiber, der kümmert sich um die Sammlung (DefaultWrites.traversableWrites
), die wiederum eine implizite Writes[A]
nimmt - in Ihrem Fall Writes[Animal]
, so wird der Compiler auswählen und übergeben Sie Ihre AnimalWrites.
, dass Ihre Liste verschiedene Arten von Tieren enthält, ist etwas, das hat, dass von den Typinformationen zu wissen, erhältlich bei Ihren Json.toJson(l)
So keine Möglichkeit, zur Laufzeit und der Compiler geschieht, wie Sie sehen, nicht erreichen können, was Sie wollen in der Art und Weise haben Sie, aber Sie können, indem man das Tier Schriftsteller wissen über die Subtypen, zum Beispiel in fast der gleichen Weise tun:
implicit object animalWrite extends Writes[Animal] {
def writes(ts: Animal) = ts match {
// this will get an implicit Writes[Dog] since d is a Dog
case d: Dog => Json.toJson(d)
// this will get an implicit Writes[Cat] since c is a Cat
case c: Cat => Json.toJson(c)
case x => throw new RuntimeException(s"Unknown animal $x")
}
}
Hope this geholfen!
Danke johanandren. Das ist hilfreich, ich dachte, das Problem hätte mit Implicits zu tun, aber ich habe nicht verstanden, wie. Was ich getan habe, um Abhilfe zu schaffen, war die Implementierung einer serialisierten Methode in Dog und Cat, die 'Json.toJson (this)' aufruft und sie mit 'l.map (_. Serialize) .mkString (" [",", ","] ")'. Deines ist besser, da du das Json nicht zusammen wie ich manuell verketten musstest. Vielen Dank. – ariscris
is'nt besser eine Funktion toJson in Tier Hexe hinzufügen, dass '' ' Fall Klasse Hund umgesetzt werden könnten (außer Kraft setzen val name: String, val Rasse: String) erweitert Tier (Name) { def toJson = Json.toJson (this) } '' ' – crak
In der Regel wird dies vermieden, da es Ihr Domain-Modell mit den Implementierungsdetails einer Form der Serialisierung mischen und eng koppeln würde, während Typklassen, die JSON spielen, typischerweise nette Entkopplungen verwendet Dies. – johanandren