你能想象這樣做:
scala> import spray.json._
import spray.json._
scala> case class Foo(bar: String) {
def toJson:JsValue = JsObject("bar" -> JsString(bar))
}
defined class Foo
scala> Foo("bar").toJson
res2: spray.json.JsValue = {"bar":"bar"}
到目前爲止好,但不適合於噴霧的類型類的機制。例如,如果您嘗試將Foo轉換爲JsValue或從JsValue轉換(例如,使用路由entity(as[Foo]) { ... }
),Spray的路由DSL會給您一個類型錯誤。也可能他們已經爲你準備的implicits,對於類型,如List和Set,與富貴工作:
scala> import DefaultJsonProtocol._
import DefaultJsonProtocol._
scala> List(Foo("bar")).toJson
<console>:31: error: Cannot find JsonWriter or JsonFormat type class for List[Foo]
List(Foo("bar")).toJson
因爲沒有JsonFormat類爲他們使用轉換符,就像一個JsonFormat1(Foo)
會已經創造出來了。
那麼你可能會認爲把富同伴對象中的格式,因爲一個在範圍內一流的同伴對象是隱式的搜索路徑,像這樣:
object Foo extends DefaultJsonProtocol {
implicit val fooFormat = jsonFormat1(Foo)
}
case class Foo(bar: String)
但是因爲我們沒有完成在這一點上定義富,編譯器爲我們提供了一個類型的錯誤:
[error] found : Foo.type
[error] required: ? => ?
[error] Note: implicit value fooFormat is not applicable here because it comes after the application point and it lacks an explicit result type
加入RootJsonFormat[Foo]
一個明確的結果類型不解決問題:
[error] found : Foo.type
[error] required: ? => Foo
[error] implicit val fooFormat:RootJsonFormat[Foo] = jsonFormat1(Foo)
訣竅(!感謝knutwalker)是明確地傳遞Foo.apply
:
object Foo extends DefaultJsonProtocol {
implicit val fooFormat = jsonFormat1(Foo.apply)
}
case class Foo(bar: String)
同伴對象是隱式的搜索範圍的一部分。在伴侶中定義它就足夠了,它將在沒有明確導入的情況下被找到。 – knutwalker
我似乎無法得到那個工作。我嘗試創建一個擴展了DefaultJsonProtocol的Foo對象,它包含'implicit val barFormat = jsonFormat1(Bar)',但是由於我還沒有完成對Bar的定義,因此編譯器不太滿意。如果你能做到這一點,你應該得到綠色支票;我會很高興地從你的答案中學習! – AmigoNico
'Foo.apply'可以做到這一點,也就是'implicit val barFormat = jsonFormat1(Foo.apply)'。我放棄了它的要點:https://gist.github.com/knutwalker/10355424 – knutwalker