盘旋编码放置::当未密封来自特征的案例类列表时

大家好,我在circe库和在scala case类之间进行转换的circe库遇到问题,我们将不胜感激。

过去我有这样的ADT。

sealed trait Sons

case class Son1(name: String, belongings: List[String]) extends Sons
case class Son2(lastName: String, belongings: List[String]) extends Sons

并且没有任何问题,但是由于设计原因,现在更改该特性的代价很高,我们必须从特性中删除密封,因此现在有了这个特性(儿子在不同的文件/库中)

trait Sons

case class Son1(name: String, belongings: List[String]) extends Sons
case class Son2(lastName: String, belongings: List[String]) extends Sons

尝试将Scala的儿子列表转换为json时,库在列表产生问题之前将::放在该示例中可以看到的问题。

object Test extends App{


implicit val encoderSon1: Encoder[Son1]=deriveEncoder[Son1]
  implicit val decoderSon1: Decoder[Son1]=deriveDecoder[Son1]
  implicit val encoderSon2: Encoder[Son2]=deriveEncoder[Son2]
  implicit val decoderSon2: Decoder[Son2]=deriveDecoder[Son2]

  implicit val encoderSon: Encoder[Sons] = Encoder.instance {
    case son1: Son1 => son1.asJson
    case son2: Son2 => son2.asJson
  }

  implicit val DecoderSon: Decoder[Sons] =
    List[Decoder[Sons]](
      Decoder[Son1].widen,
      Decoder[Son2].widen
    ).reduceLeft(_ or _)

  implicit val encoderSonList: Encoder[List[Sons]] = deriveEncoder
  implicit val DecoderSonList: Decoder[List[Sons]] = deriveDecoder

  val sonsList: List[Sons] = List(Son1("James",List()),Son2("Mike",List()))
  println(s"1->${sonsList}")
  println(s"2->${sonsList.asJson.noSpaces}")
  val andBack=decode[List[Sons]](sonsList.asJson.noSpaces).fold(fa=>fa.getMessage,fb=>fb.toString())
  println(s"3->${andBack}")
}

印刷品正在印刷

1->List(Son1(James,List()), Son2(Mike,List()))
2->{"::":[{"name":"James","belongings":[]},{"lastName":"Mike","belongings":[]}]}
3->Attempt to decode value on failed cursor: DownField(head),DownField(::)

问题是,当转换为JSON时,我当然不希望将列表放在::字段中。

谢谢您的任何可能的帮助:D

评论
  • 发霉的情书
    发霉的情书 回复

    Don't use semi auto for List - semiauto uses slightly different mechanism than other derivations to e.g. avoid issues like:

    implicit val x: X = implicitly[X] // uses val x, so we have cyclic dependency = error in runtime
    

    For that reason when you are using semiauto here, List instances from Encoder and Decoder are ignored, and instead macro generates code for List ADT - that is case class :: and case object Nil.

    如果删除

    
      implicit val encoderSonList: Encoder[List[Sons]] = deriveEncoder
      implicit val DecoderSonList: Decoder[List[Sons]] = deriveDecoder
    

    它会再次工作。