带有案例类的抽象类的scala circe编码器/解码器

Posted

技术标签:

【中文标题】带有案例类的抽象类的scala circe编码器/解码器【英文标题】:scala circe encoders/decoders for an abstract class with case classes 【发布时间】:2018-10-22 17:51:34 【问题描述】:

我想将 FieldMapping 类的集合保存为 json 字符串 -

abstract class Field 
  def clazz: Class[_]

  def name: String


case class StringField(name: String) extends Field 
  override def clazz: Class[_] = classOf[String]


case class DateField(name: String) extends Field 
  override def clazz: Class[_] = classOf[Date]

... 等 - 完整代码在这里: https://github.com/alexeyOnGitHub/scala-typesafe/blob/master/src/main/scala/com/example/model/Field.scala

Circe 代码:

import com.example.model.DateField, Field, FieldMapping, StringField
import io.circe.generic.semiauto.deriveDecoder, deriveEncoder
import io.circe.Decoder, Encoder

object CirceBoilerplateForConfigs 
  implicit val fieldDecoder: Decoder[StringField] = deriveDecoder[StringField]
  implicit val fieldEncoder: Encoder[StringField] = deriveEncoder[StringField]

  implicit val dateDecoder: Decoder[DateField] = deriveDecoder[DateField]
  implicit val dateEncoder: Encoder[DateField] = deriveEncoder[DateField]

  implicit val fooDecoder: Decoder[FieldMapping] = deriveDecoder[FieldMapping]
  implicit val fooEncoder: Encoder[FieldMapping] = deriveEncoder[FieldMapping]

错误:(14, 65) 找不到类型的惰性隐式值 io.circe.generic.decoding.DerivedDecoder[com.example.model.FieldMapping] 隐式 val fooDecoder: Decoder[FieldMapping] = derivedDecoder[FieldMapping] 错误:(14, 65)

deriveDecoder 方法的参数不足:(隐式解码: shapeless.Lazy[io.circe.generic.decoding.DerivedDecoder[com.example.model.FieldMapping]])io.circe.Decoder[com.example.model.FieldMapping]。 未指定值参数解码。隐式 val fooDecoder: 解码器[FieldMapping] = 派生解码器[FieldMapping] 错误:(15, 65)

找不到类型的惰性隐式值 io.circe.generic.encoding.DerivedObjectEncoder[com.example.model.FieldMapping] 隐式 val fooEncoder: Encoder[FieldMapping] = derivedEncoder[FieldMapping] 错误:(15, 65)

没有足够的论据 方法派生编码器:(隐式编码: shapeless.Lazy[io.circe.generic.encoding.DerivedObjectEncoder[com.example.model.FieldMapping]])io.circe.ObjectEncoder[com.example.model.FieldMapping]。 未指定的值参数编码。隐式 val fooEncoder: 编码器[FieldMapping] = 派生编码器[FieldMapping]

【问题讨论】:

在您的要点中,您没有提供GUser 的代码。 FieldMapping 也没有定义。 如果我注释掉 case class GUserFielddef userimport com.example.model...implicit val fooDecoderimplicit val fooEncoder 一切都会编译。 这里是其余代码 - github.com/alexeyOnGitHub/scala-typesafe/tree/master/src/main/… 我需要 FieldMapping 集合的编码器/解码器,因为这是我想要转换为 json 字符串的内容 How to create a Minimal, Complete, and Verifiable example 【参考方案1】:

Field 应该是一个密封特征(具有抽象类或非密封特征这不起作用)。

以下代码编译:

import java.util.Date

sealed trait Field 
  def clazz: Class[_]

  def name: String


case class StringField(name: String) extends Field 
  override def clazz: Class[_] = classOf[String]


case class DateField(name: String) extends Field 
  override def clazz: Class[_] = classOf[Date]


case class FieldMapping(fieldInConnector1: Option[Field],
                        fieldInConnector2: Option[Field],
                        selected: Boolean,
                        defaultValue: String)

import io.circe.generic.semiauto.deriveDecoder, deriveEncoder
import io.circe.Decoder, Encoder
object CirceBoilerplateForConfigs 
  implicit val stringDecoder: Decoder[StringField] = deriveDecoder[StringField]
  implicit val stringEncoder: Encoder[StringField] = deriveEncoder[StringField]

  implicit val dateDecoder: Decoder[DateField] = deriveDecoder[DateField]
  implicit val dateEncoder: Encoder[DateField] = deriveEncoder[DateField]

  implicit val fieldDecoder: Decoder[Field] = deriveDecoder[Field]
  implicit val fieldEncoder: Encoder[Field] = deriveEncoder[Field]

  implicit val fooDecoder: Decoder[FieldMapping] = deriveDecoder[FieldMapping]
  implicit val fooEncoder: Encoder[FieldMapping] = deriveEncoder[FieldMapping]

【讨论】:

以上是关于带有案例类的抽象类的scala circe编码器/解码器的主要内容,如果未能解决你的问题,请参考以下文章

Scala使用circe将None编码为NaN json值

使用 circe 将 Scala None 编码为 JSON 值

Scala 集合的数据集编码器

创建一个扩展抽象类的对象并将其添加到 Scala 中类型抽象类的序列中

Scala快速入门--抽象类的使用

使用 circe 在 Scala 中 JSON 将嵌套字段解码为 Map[String, String]