JsonFormat用于具有泛型参数的抽象类 [英] JsonFormat for abstract class with generic parameter
问题描述
我正在尝试为具有通用参数的抽象类编写JsonFormat,如下所示:
I am trying to write a JsonFormat for an abstract class with a generic parameter that looks like something like this:
abstract class Animal[A] {
def data: A
def otherStuff: String = "stuff"
}
case class CatData(catField: String)
case class Cat(data: CatData) extends Animal[CatData]
到目前为止,我对此的尝试如下:
So far my attempt at this looks like:
object AnimalProtocol extends DefaultJsonProtocol {
implicit val catDataFormat = jsonFormat1(CatData)
implicit val catFormat = jsonFormat1(Cat)
implicit def animalFormat[T <: Animal[T]](t: T)(implicit fmt: JsonWriter[T]) = new RootJsonFormat[Animal[T]] {
def write(obj: Animal[T]) = obj match {
case x: Cat => catFormat.write(x)
}
def read(json: JsValue) = ???
}
现在,如果我尝试这样做:
Now, if I try to do this:
import AnimalProtocol._
val cat: Animal[CatData] = Cat(CatData("this is cat data"))
我收到编译器错误:
Cannot find JsonWriter or JsonFormat type class for Animal[CatData]
我如何使其起作用?最后,我想编写Animal
中的字段并将data
设置为适用的大小写类的json.
How can I make it work? In the end I want to write json with the fields in Animal
and with data
set to whatever case class applies.
推荐答案
您需要为implicit def
中的Animal的通用字段和子类提供类型参数:
You need to provide a type parameter for both the generic field and the subclass of Animal in your implicit def
:
object AnimalProtocol2 extends DefaultJsonProtocol {
implicit val catDataFormat = jsonFormat1(CatData)
implicit def animalFormat[A, T <: Animal[A]](implicit fmt: JsonWriter[A]): RootJsonFormat[T] = new RootJsonFormat[T] {
def write(obj: T) = {
JsObject(
"data" -> obj.data.toJson,
"otherStuff" -> obj.otherStuff.toJson
)
}
def read(json: JsValue) = ???
}
}
这也使您可以摆脱animalFormat
内部子类的模式匹配.
That also allows you to get rid of pattern matching on subclasses inside animalFormat
.
这篇关于JsonFormat用于具有泛型参数的抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!