我不喜欢将隐式参数加入到我的代码中,所以在我使用它们时我想封装它们的用法。所以我试图定义一个对象,它既包含对异常处理的spray-json的调用,又包含每个模型类的默认隐式JsonFormats。但是,隐式参数不会被解析,除非它们被导入到客户端,调用代码,这正是我不想要它们的地方。这是我到目前为止(没有解决隐式格式化程序),有没有办法可以得到我想要的工作?
package com.rsslldnphy.json
import com.rsslldnphy.models._
import spray.json._
object Json extends DefaultJsonProtocol {
implicit val personFormat = jsonFormat1(Person)
implicit val animalFormat = jsonFormat1(Animal)
def parse[T](s:String)(implicit reader: JsonReader[T]): Option[T] = {
try { Some(JsonParser(s).convertTo[T]) }
catch { case e: DeserializationException => None }
}
}
NB。 JsonFormat是一种JsonReader
编辑:这是我根据@ paradigmatic的第二个建议(我无法开始工作,我仍然得到Cannot find JsonReader or JsonFormat type class for T
)所写的内容。我错过了什么吗?
object Protocols extends DefaultJsonProtocol {
implicit val personFormat = jsonFormat1(Person)
implicit val animalFormat = jsonFormat1(Animal)
}
object Json {
def parse[T](s:String): Option[T] = {
import Protocols._
try { Some(JsonParser(s).convertTo[T]) }
catch { case e: DeserializationException => None }
}
}
对于记录,这是一个可行的代码片段,但我正在努力避免,因为它需要太多的客户端代码(即它需要在范围内具有含义):
object Json extends DefaultJsonProtocol {
implicit val personFormat = jsonFormat1(Person)
implicit val animalFormat = jsonFormat1(Animal)
}
object ClientCode {
import Json._
def person(s: String): Person = JsonParser(s).convertTo[Person]
}
答案 0 :(得分:7)
您可以在随播对象中声明隐含:
object Person {
implicit val personFormat: JReader[Person] = jsonFormat1(Person)
}
object Animal {
implicit val animalFormat: JReader[Animal] = jsonFormat1(Animal)
}
隐式解决规则非常复杂。您可以在此blog post中找到更多信息。但是如果编译器正在寻找类型类T[A]
,它将在类/特性A
的伴随对象中查看(很快或稍后)它。
编辑:如果问题只是范围问题"污染",您可以介绍一些大括号。使用您的代码示例,您可以将函数解析称为:
package com.rsslldnphy.json
import com.rsslldnphy.models._
import spray.json._
object Json extends DefaultJsonProtocol {
implicit val personFormat = jsonFormat1(Person)
implicit val animalFormat = jsonFormat1(Animal)
def parse[T](s:String)(implicit reader: JsonReader[T]): Option[T] = {
try { Some(JsonParser(s).convertTo[T]) }
catch { case e: DeserializationException => None }
}
}
object JsonFacade {
def optParse[T]( s: String ): Option[T] = {
import Json._
parse[T]( s )
}
}
这里暗示"污染"只有optParse
方法。