2016-09-23 6 views
4

Так у меня есть следующий код:Scala Compiler (2.11.7) аномалию с Play JSON Пишет

Основание:

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 = { 
     val cost = r.cost.map(Json.toJson(_)).getOrElse(JsNull) 
     Json.obj(
     "cost" -> cost 
    ) 
    } 
    } 
} 

Но это не компиляция

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

Ошибка компилятора заключается в следующем ING:

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

В последнем случае, если я использую .asInstanceOf [JsValue] он работает, но с IntelliJ серости это, говоря, что это нужно, поскольку она не может быть ничего, что JsValue в любом случае. Что может быть причиной того, что компилятор Scala (2.11.7) не обнаруживает класс должным образом?

+0

Компиляция непосредственно с SBT? – cchantep

+0

Да компиляция из SBT. – mpartan

ответ

2

Я довольно уверен, что проблема исходит от .getOrElse(JsNull)

Я успешно скомпилирован этот код:

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(_)) 
    ) 
    } 
    } 
} 

и проанализирован выход:

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

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

Глядя на источник Вы можете проверить пару дополнительных решений, предполагая, что функция write ион:

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

если вы хотите разрешить Option из cost значения с getOrElse вы можете заливку (как вы попробовали) или предоставить тип:

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

и без спецификации типа sbt всегда приводит к ошибке:

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

, который должен исходить из ошибки компилятора SBT.

+0

Это похоже на работу, как и я. Раньше я использовал по умолчанию def write = Json.writes [Cost], который не содержит никаких None-полей в JSON как null, что и требовалось API. Он еще не объясняет ошибку типа компилятора в исходном сообщении, поскольку JsNull - это JsValue, а также возвращаемое значение Json.toJson. – mpartan

+0

@mpartan Должно быть ошибка SBT. См. Обновление. – Atais