Scala 编译器 (2.11.7) Play JSON 写入异常

Scala Compiler (2.11.7) anomaly with Play JSON Writes

所以我有以下代码:

基数:

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}

寻找问题的根源,你可以检查几个额外的解决方案,假设 writes 函数:

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

如果您想用 getOrElse 解析 cost 值的 Option,您可以强制转换(如您所试)或提供类型:

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 的一些编译器错误造成的。