scala - 找不到参数编码器 : io. circe.Encoder[com.sweetsoft.SapHealth] 的隐含值

标签 scala circe

我有以下代码,无法编译:

import java.time.Instant

import io.circe.{Decoder, Encoder}
import io.circe.generic.auto._
import io.circe.syntax._

trait SapHealth {}

case class SapHealthRejected(reason: String) extends SapHealth

case class SapHealthAccepted(sapId: String, requestedAt: Long) extends SapHealth


object SapHealth {

  private val build: SapHealth = SapHealthAccepted(SapmockActor.system.name, Instant.now().getEpochSecond)

  val create: String = build.asJson.noSpaces

  implicit val encodeFieldType: Encoder[SapHealthAccepted] =
    Encoder.forProduct2("sap-id", "requested_at")(SapHealthAccepted.unapply(_).get)

  implicit val decodeFieldType: Decoder[SapHealthAccepted] =
    Decoder.forProduct2("sap-id", "requested_at")(SapHealthAccepted.apply)

}

编译器提示:
could not find implicit value for parameter encoder: io.circe.Encoder[com.sweetsoft.SapHealth]
[error]   val create: String = build.asJson.noSpaces

我错过了什么?

最佳答案

您已经专门向上转换 buildSapHealth ,但您没有提供 Encoder SapHealth 的实例(仅 SapHealthAccepted ),并且 circe-generic 无法派生,因为您尚未密封特征层次结构。

最直接的解决方案是添加 sealed :

import io.circe.{Decoder, Encoder}
import io.circe.generic.auto._
import io.circe.syntax._

sealed trait SapHealth {}
case class SapHealthRejected(reason: String) extends SapHealth
case class SapHealthAccepted(sapId: String, requestedAt: Long) extends SapHealth

object SapHealth {
  implicit val encodeFieldType: Encoder[SapHealthAccepted] =
    Encoder.forProduct2("sap-id", "requested_at")(SapHealthAccepted.unapply(_).get)

  implicit val decodeFieldType: Decoder[SapHealthAccepted] =
    Decoder.forProduct2("sap-id", "requested_at")(SapHealthAccepted.apply)

  private val build: SapHealth = SapHealthAccepted("foo", 123L)

  val create: String = build.asJson.noSpaces
}

请注意,您还需要重新排列定义以避免由于初始化顺序而遇到空指针异常(如果您将 create 放在 encodeFieldType 之前,则派生的 SapHealth 编码器将在初始化之前尝试使用 encodeFieldType) .通过上面的重新排列,这很好用:
scala> SapHealth.create
res2: String = {"SapHealthAccepted":{"sap-id":"foo","requested_at":123}}

注意派生的 SapHealth编码器正在使用您的自定义 SapHealthAccepted编码器,我认为这是您想要的。

关于scala - 找不到参数编码器 : io. circe.Encoder[com.sweetsoft.SapHealth] 的隐含值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56380018/

相关文章:

用于转换为 `Option` 的 Scala 语法糖

json - 斯卡拉和瑟茜 : JSON encoding with optional fields

json - 如何在没有案例类的情况下解析 JSON Scala

scala - 使用 Circe 解码 Normal Class(不是 case class)

Scala,PureConfig - 如何读取 json 配置文件?

json - 将嵌套对象编码为字符串

maven-2 - jruby 的 Sbt 插件

scala - 使用spark访问HDFS失败

scala - 尝试使用类型参数编写 DRY Scala 代码

xml - 在 Scala 中使用动态标签和属性构造 XML?