问题描述
我有一个案例类 Student,其中包含 Animal 特征的实例,以及扩展该特征的两个案例类 Cat 和 Dog。我无法弄清楚如何正确编码和解码 Student 类的实例。
目标 了解如何将 Student 实例正确编码为 JSON。 了解将 JSON 表示返回到 Student 实例的适当解码过程。
import io.circe._
import io.circe.generic.semiauto._
trait Animal
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal
case class Student(id: Int, name: String, animal: Animal)
object Student {
implicit val catEncoder: Encoder[Cat] = deriveEncoder
implicit val catDecoder: Decoder[Cat] = deriveDecoder
implicit val dogEncoder: Encoder[Dog] = deriveEncoder
implicit val dogDecoder: Decoder[Dog] = deriveDecoder
implicit val animalEncoder: Encoder[Animal] = deriveEncoder
implicit val animalDecoder: Decoder[Animal] = deriveDecoder
implicit val studentEncoder: Encoder[Student] = deriveEncoder
implicit val studentDecoder: Decoder[Student] = deriveDecoder
}
object Test extends App {
import io.circe.syntax._
val student = Student(1, "abc", Cat("cat"))
val jsonString = student.asJson.noSpaces
println("JSON representation: " + jsonString)
val decoded: Either[io.circe.Error, Student] = io.circe.parser.decode[Student](jsonString)
println("Decoded Student: " + decoded)
}
如果您想为层次结构的父特征派生类型类(编解码器),则必须密封该特征
sealed trait Animal
https://scastie.scala-lang.org/DmytroMitin/td1vmuCESZePhxno7VYwUw/4
与
Student
相反,对于 Cat
、Dog
、Animal
,类型类 Encoder
/Decoder
的实例现在放置在隐式范围之外。
类型
SomeTypeclass[SomeDatatype]
的隐式应放置在 SomeTypeclass
或 SomeDatatype
的伴生对象中。然后隐式将无需导入即可使用。所以你最好写一下
sealed trait Animal
object Animal {
implicit val animalEncoder: Encoder[Animal] = deriveEncoder
implicit val animalDecoder: Decoder[Animal] = deriveDecoder
}
case class Cat(name: String) extends Animal
object Cat {
implicit val catEncoder: Encoder[Cat] = deriveEncoder
implicit val catDecoder: Decoder[Cat] = deriveDecoder
}
case class Dog(name: String) extends Animal
object Dog {
implicit val dogEncoder: Encoder[Dog] = deriveEncoder
implicit val dogDecoder: Decoder[Dog] = deriveDecoder
}
case class Student(id: Int, name: String, animal: Animal)
object Student {
implicit val studentEncoder: Encoder[Student] = deriveEncoder
implicit val studentDecoder: Decoder[Student] = deriveDecoder
}
https://scastie.scala-lang.org/DmytroMitin/td1vmuCESZePhxno7VYwUw/2