具有动物特征的学生案例类的编码和解码

问题描述 投票:0回答:1

问题描述

我有一个案例类 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)
}

scala circe http4s-circe
1个回答
0
投票

如果您想为层次结构的父特征派生类型类(编解码器),则必须密封该特征

sealed trait Animal

https://scastie.scala-lang.org/DmytroMitin/td1vmuCESZePhxno7VYwUw/4

Student
相反,对于
Cat
Dog
Animal
,类型类
Encoder
/
Decoder
的实例现在放置在隐式范围之外。

Scala 在哪里寻找隐式?

类型

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

© www.soinside.com 2019 - 2024. All rights reserved.