简体   繁体   English

如何使用多个apply方法为案例类定义Json格式?

[英]How do I define Json format for a case class with more than one apply method?

Scala and spray-json together make life extremely easy to define how to serialize and deserialize instances of case classes. Scala和spray-json在一起使定义定义序列化实例类实例的方式变得非常容易。 [Other Json libraries are, no doubt, just as easy to use.] [毫无疑问,其他Json库同样易于使用。]

But there is one problem for which I have not been able to find an answer here on StackOverflow, or elsewhere. 但是有一个问题,在这里我无法在StackOverflow或其他地方找到答案。 What if you have a case class, with an explicitly defined object, such that there is at least one additional apply method defined? 如果您有一个带有明确定义的对象的case类,那么至少定义了一个附加的apply方法怎么办?

For example, let's say that our case class is called RuleSet and is defined thus (with some additional method signatures which are not important): 例如,假设我们的案例类称为RuleSet,并因此定义(带有一些不重要的其他方法签名):

case class RuleSet(rules: Map[String, Rule[String]])

And the object is defined thus: 并因此定义了对象:

object RuleSet {
  def apply(): RuleSet = apply(Map[String, Rule[String]]())
  // ... other method definitions ...
}

Assuming that we have an implicit Json format in scope for Rule, we should be able to define a Json protocol for RuleSet as follows: 假设我们在Rule范围内具有隐式Json格式,则应该能够为RuleSet定义Json协议,如下所示:

import spray.json._
object RuleProtocol extends DefaultJsonProtocol {
  implicit val ruleSetFormat = jsonFormat1(RuleSet.apply)
}

Unfortunately, this gives an error: Error(213,54) ambiguous reference to overloaded definition... 不幸的是,这给出了一个错误:Error(213,54)对重载定义的含糊不清的引用...

What's to be done? 怎么办?

Well, I did figure out a solution and will post it here as an answer to my own question so that others may save themselves the time it took me to work it out. 好吧,我确实找到了解决方案,并将其发布在这里,作为对我自己问题的回答,以便其他人可以节省自己解决我的时间。

The solution is to create a variable which is an explicit signature of the apply method, by appealing to the compiler's type inferencing: 解决方案是通过吸引编译器的类型推断来创建一个变量,该变量是apply方法的显式签名:

object RuleProtocol extends DefaultJsonProtocol {
  val ruleSetApply: (Map[String,Rule[String]]=>RuleSet) = RuleSet.apply
  implicit val ruleSetFormat = jsonFormat1(ruleSetApply)
}

That's all you need to do: just make it explicit which apply method you want to use. 这就是您需要做的所有事情:只需明确指出要使用的应用方法即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM