Scala编译器(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)
      )
    }
  }
}

编译器错误如下:

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)无法正确检测Class的原因可能是什么?

最佳答案 我很确定这个问题来自.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}

寻找问题的根源,你可以检查几个额外的解决方案,假设写入功能:

val cost = r.cost.map(t => Json.toJson(t))
Json.obj(
  "cost" -> 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的编译器错误.

点赞