2017-12-04 11 views
0

私はスプレーjsonの例を探しています、最後の行val color = json.convertTo[Color]は、クラス型を指定する関数呼び出しを持っていますか?ほぼ型定義を定数に代入するように見えます。そのコンテキストで何が起こっているのか誰かが説明できますか?スカラの型定義のようなメソッド呼び出し

case class Color(name: String, red: Int, green: Int, blue: Int) 
object MyJsonProtocol extends DefaultJsonProtocol { 
    implicit val colorFormat = jsonFormat4(Color) 
} 

import MyJsonProtocol._ 
import spray.json._ 

val json = Color("CadetBlue", 95, 158, 160).toJson 
val color = json.convertTo[Color] 

おかげ

+2

https://docs.scala-lang.org/tour/polymorphic-methods.htmlがあなたの混乱に対処していますか? –

答えて

3

それはあなたに、まさにそれが明確ではない明確ではありません。変数jsonのタイプはJsValueです。そのクラスは

def convertTo[T :JsonReader]: T = jsonReader[T].read(this) 

このコードとして指定ジェネリックconvertTo方法はconvertToタイプコンテキストにおいて可視JsonReader[T]の暗黙オブジェクトがされている任意のタイプTために呼び出すことができることを意味しています。だから、これはコンパイラの魔法の一部と同じコードです。

def convertTo[T](implicit jsonReader: JsonReader[T]): T = jsonReader.read(this) 

だからこのトリックは何ですか?あなたがSpray JSONライブラリの作者であると考えてください。明らかにJSONから妥当にデコードできない多くの型があります(例えば、Threadをデコードするのはどういう意味ですか?)。したがって、少なくとも理論的にデコードされる可能性がある型のデコードだけを許すという意味で、JsValue.convertToメソッドを「型安全」にしたいとします。残念ながら、この100%を自動的に決定することはかなり難しい作業です。 Still Spray JSON(他の多くのScala JSONライブラリと同様)は、それに近似しています。このアイデアは、正確にこのプロパティを符号化するtype classJsonReader[T]と宣言しています。タイプTはJSONからデコードできます。次に、型クラスのメンバーである型だけをデコードする必要があります。 Scalaのこのタイプのクラスアイデアは、通常implicitsを使用して実装されます。つまり、証拠を明示的に渡すのではなく、証拠を見つけるためにコンパイラに依存します。 Althougのコンパイラはしばしばコンテキストだけで適切なジェネリック型の置換を推論することができます。この特定のケースではコンテキストがないので、型を明示的に指定する必要があります。マクロ:

implicit val colorFormat = jsonFormat4(Color) 

を並べる

注意は別の強力なScalaのトリックを使用しています。 Spray JSONは、多くの型の型クラスの証拠を自動的に生成するマクロライブラリを提供します。

関連する問題