2016-09-23 2 views
4

So habe ich den folgenden Code:Scala Compiler (2.11.7) Anomalie mit Play JSON Schreibt

Basis:

import play.api.libs.json.{JsNull, Json, JsValue, Writes} 
case class Cost(cost: Option[Double]) 

Dies kompiliert:

case object Cost { 
    def writes = new Writes[Cost] { 
    override def writes(r: Cost): JsValue = { 
     val cost = r.cost.map(Json.toJson(_)).getOrElse(JsNull) 
     Json.obj(
     "cost" -> cost 
    ) 
    } 
    } 
} 

Aber das tut nicht Kompilieren

case object Cost { 
    def writes = new Writes[Cost] { 
    override def writes(r: Cost): JsValue = { 
     Json.obj(
     "cost" -> r.cost.map(Json.toJson(_)).getOrElse(JsNull) 
    ) 
    } 
    } 
} 

Compiler-Fehler ist der folgende ing:

type mismatch; 
[error] found : Object 
[error] required: play.api.libs.json.Json.JsValueWrapper 
[error]   "cost" -> r.cost.map(Json.toJson(_)).getOrElse(JsNull) 

Im letzteren, wenn ich .asInstanceOf verwenden [JsValue] es funktioniert, aber mit IntelliJ Grau- es heraus sagen, dass es nicht notwendig ist, da es nichts anderes, dass JsValue sowieso sein kann. Was könnte der Grund dafür sein, dass der Scala-Compiler (2.11.7) die Klasse nicht korrekt erkennt?

+0

Kompilieren direkt mit SBT? – cchantep

+0

Ja, kompiliert von SBT. – mpartan

Antwort

2

Ich bin ziemlich sicher, dass die Ausgabe von .getOrElse(JsNull)

kommt habe ich erfolgreich diesen Code kompiliert:

import play.api.libs.json.{JsNull, Json, JsValue, Writes} 

case class Cost(cost: Option[Double]) 

case object Cost { 
    def writes = new Writes[Cost] { 
    override def writes(r: Cost): JsValue = { 
     Json.obj(
     "cost" -> r.cost.map(Json.toJson(_)) 
    ) 
    } 
    } 
} 

und analysiert die Ausgabe:

scala> Cost(Some(5)) 
res2: Cost = Cost(Some(5.0)) 

scala> Json.toJson(res2)(Cost.writes) 
res5: play.api.libs.json.JsValue = {"cost":5} 

für die Quelle der Suche des Problems können Sie einige zusätzliche Lösungen überprüfen, vorausgesetzt, die Schreibfunktion funktioniert Ion:

val cost = r.cost.map(t => Json.toJson(t)) 
Json.obj(
    "cost" -> cost 
) 

, wenn Sie die Option von cost Wert mit getOrElse lösen möchten, können Sie entweder gegossen (wie Sie versucht haben) oder die Art bieten:

cost.getOrElse[JsValue](JsNull) 
cost.getOrElse(JsNull).asInstanceOf[JsValue] 

und ohne die Typangabe sbt immer gibt einen Fehler Spruch:

[error] (...) type mismatch; 
[error] found : Object 
[error] required: play.api.libs.json.Json.JsValueWrapper 

, die von einigen SBT Compiler Fehler kommen müssen.

+0

Das scheint so zu funktionieren, wie ich es mir wünsche. Zuvor verwendete ich def def = Json.writes [Kosten], die keine None-Felder im JSON als null enthält, was die API benötigt. Es erklärt nicht immer noch den Compiler-Typ-Fehler im ursprünglichen Post, da JsNull JsValue sowie der Rückgabewert von Json.toJson ist. – mpartan

+0

@mpartan Muss SBT Fehler sein. Siehe Aktualisierung. – Atais