为什么 spray-json 在 RootJsonFormat 中应用这种层级方式?

Why does spray-json apply this hierarchy way in RootJsonFormat?

最近在看Spray-json的源码。我在JsonFormat.scala中注意到下面的层级关系,请看下面的代码片段

/**
* A special JsonFormat signaling that the format produces a legal JSON root 
*  object, i.e. either a JSON array
* or a JSON object.
*/
trait RootJsonFormat[T] extends JsonFormat[T] with RootJsonReader[T] with RootJsonWriter[T]

为了更方便表达混淆,我画了如下层次图:

根据我对 Scala 的有限了解,我认为 JsonFormat[T] with 应该从上面的代码中删除。然后我克隆了 Spary-json 的存储库,并注释了代码 JsonFormat[T] with

trait RootJsonFormat[T] extends RootJsonReader[T] with RootJsonWriter[T]

然后我在 SBT 中编译它(使用 package/compile 命令),它传递给编译过程并成功生成 spray-json_2.11-1.3.4.jar

然而,当我通过SBT的test命令运行测试用例时,它失败了。

所以我想知道为什么。提前致谢。

我建议你不要从OOP的角度去想。从类型 classes 的角度来考虑它。如果某些实体必须同时序列化和反序列化,则有一个类型 class JsonFormat 包括 JsonWriterJsonReader。这很方便,因为当您需要两种功能时不需要搜索 2 type class 实例。但是为了使这种方法起作用,必须有一个 JsonFormat 类型 class 的实例。这就是为什么你不能把它从层次结构中扔掉的原因。例如:

def myMethod[T](t: T)(implicit format: JsonFormat[T]): Unit = { 
  format.read(format.write(t))
}

如果您希望此方法正常工作,则必须有 JsonFormat 的直接后代和特定类型的具体隐式实例 T

UPD: 通过创建 JsonFormat 类型 class 的实例,您可以获得 JsonWriterJsonReader 的实例自动输入 classes(以防两者都需要)。所以这也是减少样板文件的一种方式。