简体   繁体   中英

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. [Other Json libraries are, no doubt, just as easy to use.]

But there is one problem for which I have not been able to find an answer here on StackOverflow, or elsewhere. What if you have a case class, with an explicitly defined object, such that there is at least one additional apply method defined?

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):

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:

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...

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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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