我正在使用 play 框架,并有一个抽象类:
abstract class Base{...}
它在伴随对象中有自己的隐式 JSON 编写器
object Base {
implicit val baseWrites: Writes[Base] = (...)(unlift(Base.unapply))
}
我继承了这个抽象类:
case class SubClass{...}
它的伴生对象中也有自己的隐式 JSON 编写器
object SubClass {
implicit val subClassWrites: Writes[SubClass] = (...)(unlift(SubClass.unapply))
}
当我尝试使用 Json.toJson(SubClass) 序列化子类对象时,出现错误:
[error] both value subClassWrites in object SubClass of type => play.api.libs.json.
Writes[models.SubClass]
[error] and value baseWrites in object Base of type =>
play.api.libs.json.Writes[models.Base]
[error] match expected type play.api.libs.json.Writes[models.SubClass]
[error] Ok(Json.toJson(SubClass.find(id)))
有什么办法可以消除歧义吗?
最佳答案
您正在发生碰撞,因为 Writes
有一个逆变类型参数 A
:
trait Writes[-A] extends AnyRef
这意味着
Writes[Base]
是 Writes[SubClass]
的子类- 您可以使用 Writes[Base]
哪里Writes[SubClass]
是必须的。问题在这里:
val base: Base = new SubClass(...)
val jsBase = Json.toJson(base)
所以
Writes[Base]
应该能够序列化 SubClass
的实例.您可以使用 ADT
在这种情况下:sealed trait Base
object Base {
implicit val baseWrites: Writes[Base] =
new Writes[Base]{
def writes(o: Base): JsValue = o match {
case s: SubClass => SubClass.writes.writes(s)
case s: SubClass2 => SubClass2.writes.writes(s)
}
}
}
case class SubClass(...) extends Base
object SubClass {
val writes: Writes[SubClass] = (...)(unlift(SubClass.unapply))
}
case class SubClass2(...) extends Base
object SubClass2 {
val writes: Writes[SubClass2] = (...)(unlift(SubClass2.unapply))
}
与
sealed
关键字你会收到警告 match
并不详尽。
关于json - Play json 写入子类给出不明确的隐含值错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21034135/