在子类中重用 json 隐式读取器

Posted

技术标签:

【中文标题】在子类中重用 json 隐式读取器【英文标题】:Reuse json implicit readers in subclasses 【发布时间】:2015-12-08 12:13:22 【问题描述】:

想象以下场景:

我有两个类,一个扩展另一个。我想定义隐式读取以从 json 转换为类。 看例子:

case class A(field1: String, field2: Int)

object A 
  implicit val reads: Reads[A] = (
    (__ \'field1).read[String] and
    (__ \'field2).read[Int]
  )(A.apply _)


case class B(field1: String, field2: Int, field3: Boolean)

object B 
  implicit val reads: Reads[B] = (
    (__ \'field1).read[String] and
    (__ \'field2).read[Int] and
    (__ \'field3).read[Boolean]
  )(B.apply _)

我的问题是如何避免隐式读取中的代码重复。 如果 B 类扩展 A,Reads[B] 如何重用 Reads[A] 并避免阅读器中的代码重复? 我知道在这种情况下,B 类没有扩展 A,因为它们被定义为案例类。我可以将它们的定义更改为普通类,甚至在需要时定义一个特征。

我需要以 B 是 A

的方式保持类之间的关系

谢谢。

【问题讨论】:

【参考方案1】:

你可以试试:

import play.api.libs.json._
import play.api.libs.functional.syntax._

object A 
  val readsFields = (__ \'field1).read[String] and (__ \'field2).read[Int]
  implicit val reads: Reads[A] = (
    aReadsFields
  )(A.apply _)


object B 
  implicit val reads: Reads[B] = (
    A.readsFields and
    (__ \'field3).read[Boolean]
  )(B.apply _)

您也可以定义类之间的关系:

case class A(field1: String, field2: Int)

object A 
  implicit val reads: Reads[A] = (
    (__ \'field1).read[String] and
    (__ \'field2).read[Int]
  )(A.apply _)


case class B(field1: A, field3: Boolean)

object B 
  implicit val reads: Reads[B] = (
    (__ \'field1).read[A] and
    (__ \'field3).read[Boolean]
  )(B.apply _)

查看播放框架教程了解详情: https://www.playframework.com/documentation/2.4.x/ScalaJson

【讨论】:

感谢您的想法。这解决了我的问题。不知道为什么我以前不记得了。关于替代方案,对我来说不起作用,因为它会改变类之间的关系。 B 包含 A 但 B 不是 A。

以上是关于在子类中重用 json 隐式读取器的主要内容,如果未能解决你的问题,请参考以下文章

继承:继承后子类构造函数具有隐式super

Java除了数字类型的自动隐式类型转换,对类有类似功能么?

UIControl子类-意外地找到nil,同时隐式展开一个可选值

JAVA中,子类继承时构造方法注意事项

使用 Circe Json 为啥隐式解析在运行时会变慢

使用隐式意图读取图库文件夹