circe encoding putting :: 当来自 trait 的 case class 列表未密封时
circe encoding putting :: when a list of case class from trait is not sealed
大家好,我在 json 和 scala 案例 class 之间进行翻译时遇到了 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
没有任何问题,但现在由于设计 中的文件,这个特征是,改变成本很高,我们必须从特征中删除密封,所以现在我们有了这个(和儿子们一起在不同的 files/libraries)
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}")
}
打印为 printint
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
不要为 List
使用半自动 - semiauto 使用与其他派生略有不同的机制,例如避免以下问题:
implicit val x: X = implicitly[X] // uses val x, so we have cyclic dependency = error in runtime
出于这个原因,当您在这里使用 semiauto 时,来自 Encoder
和 Decoder
的 List
实例将被忽略,取而代之的是宏为 List
ADT 生成代码 - 即是 case class ::
和 case object Nil
.
如果删除
implicit val encoderSonList: Encoder[List[Sons]] = deriveEncoder
implicit val DecoderSonList: Decoder[List[Sons]] = deriveDecoder
它将再次起作用。
大家好,我在 json 和 scala 案例 class 之间进行翻译时遇到了 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
没有任何问题,但现在由于设计 中的文件,这个特征是,改变成本很高,我们必须从特征中删除密封,所以现在我们有了这个(和儿子们一起在不同的 files/libraries)
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}")
}
打印为 printint
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
不要为 List
使用半自动 - semiauto 使用与其他派生略有不同的机制,例如避免以下问题:
implicit val x: X = implicitly[X] // uses val x, so we have cyclic dependency = error in runtime
出于这个原因,当您在这里使用 semiauto 时,来自 Encoder
和 Decoder
的 List
实例将被忽略,取而代之的是宏为 List
ADT 生成代码 - 即是 case class ::
和 case object Nil
.
如果删除
implicit val encoderSonList: Encoder[List[Sons]] = deriveEncoder
implicit val DecoderSonList: Decoder[List[Sons]] = deriveDecoder
它将再次起作用。