Scala 编码 None 到 NaN json 值与 circe

Scala encoding None to NaN json value with circe

我有一个通过 HTTP 调用 TensorFlow 服务的 Scala 服务。 我正在尝试使用 circe 将 None 值编码为 NaN 为 JSON(TensorFlow 如何期望它),但是在编码对象

之后我得到“null”

假设我有以下案例 class 需要使用 circe 序列化为 JSON 对象:

case class MyRequest(instance: Option[Double])

object MyRequest extends CirceDefaults {
  implicit val autoEncoderRequestEncoder: Encoder[MyRequest] = { (myRequest: MyRequest) =>
    myRequest.instance match {
      case Some(value) => Json.fromDouble(value).asJson
      case None => None.asJson
    }
  }
}

所以 None.asJson 编码为“null”而不是 NaN,我从 tensorflow 服务中收到错误:

Error: Invalid argument: JSON Value: "null" Type: String is not of expected type: float"

如有任何帮助,我们将不胜感激。

这是 Circe 的默认行为。请查看更多详情:https://github.com/circe/circe/issues/1267

似乎不​​仅对于 Circe,而且一般来说 JSON 标准没有 Nan、-Infinity、+Infinity 这样的东西,所以在 Circe 中,你甚至不能创建 Json Double.Nan: https://github.com/circe/circe/blob/master/modules/core/shared/src/main/scala/io/circe/Json.scala#L517

所以 Json.fromDouble(Double.Nan) returns None - 因为 Double.Nan 不是真实的:https://github.com/circe/circe/blob/master/modules/core/shared/src/main/scala/io/circe/Json.scala#L575

因此,为了按照您想要的方式呈现 Nan,不幸的是,您需要在呈现后编辑 JSON 字符串

import io.circe._, io.circe.generic.semiauto._, io.circe.syntax._

case class MyRequest(instance: Option[Double])

object MyRequest {
  implicit val encoder: Encoder[MyRequest] = request => {
    request.instance.fold(Json.fromString("NaN"))(_.asJson)
  }
}

case class BigRequest(request: MyRequest)

object BigRequest {
  implicit val encoder: Encoder[BigRequest] = deriveEncoder[BigRequest]
}

println(BigRequest(MyRequest(Some(1.0d))).asJson.noSpaces)

println(BigRequest(MyRequest(None)).asJson.noSpaces.replace(""""NaN"""", "NaN"))

斯凯蒂:https://scastie.scala-lang.org/SGHtB9GZRpShtQ6A8qAZsA