私はこのjsonコンビネータをいくつかの基本的/標準的なケースで使用してきましたが、それがどのように機能するかを本当に理解していません。すべて問題ありませんでした。
今、私はどんな高度なケースが来ても準備を整えたいと思っています。コードを理解する必要があります。
参考:https ://www.playframework.com/documentation/2.3.x/ScalaJsonCombinators
私はReadsを理解できると思います:
implicit val locationReads: Reads[Location] = (
(JsPath \ "lat").read[Double] and
(JsPath \ "long").read[Double]
)(Location.apply _)
次の読み取りを作成します。
最初に ("reads" メソッドを介して) JsValue が指定されると、"lat" が取得され、続いて "long" が取得されます。これら 2 つからタプル (Double、Double) を作成します。-- https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.json.Reads
そのタプルは、その Reads... の部分関数に割り当てられます。この場合は、「Location.apply _」によって返されるものです。私はreplでそれを試しました:
...
scala> val yowMan = Location.apply _
yowMan: (Double, Double) => Location = <function2>
scala> yowMan(1, 2)
res14: Location = Location(1.0,2.0)
その部分関数は (Double, Double) のタプルを入力として受け取ります。したがって、ステップ 1 の結果はステップ 2 に送られ、"reads" の戻り値として Location のインスタンスが取得されます。
では、次のように書き込みます。
implicit val locationWrites: Writes[Location] = (
(JsPath \ "lat").write[Double] and
(JsPath \ "long").write[Double]
)(unlift(Location.unapply))
まず「申請を取り消す」。私はreplで試しました:
scala> val heyDude = Location.unapply
<console>:16: error: missing arguments for method unapply in object Location;
follow this method with `_' if you want to treat it as a partially applied function
val heyDude = Location.unapply
おっと、わかりました、私は指示に従いました:
scala> val heyDude = Location.unapply _
heyDude: Location => Option[(Double, Double)] = <function1>
では、Location のインスタンスを (オプションの) (Double, Double) のタプルに変換する部分関数を取得します。
次に、「アンリフト」:
scala> val hohoho = unlift(heyDude)
hohoho: Location => (Double, Double) = <function1>
scala> val loc = Location(1, 2)
loc: Location = Location(1.0,2.0)
scala> hohoho(loc)
res16: (Double, Double) = (1.0,2.0)
わかりました... unlift は単純に「オプション」を破棄し、タプルに直接移動します。
わかりました...そう...私は推測します...これはWritesの「書き込み」です... *) Locationのインスタンスが与えられると、次のようになります:
そのオブジェクトを unlift(Location.unapply) によって生成された部分関数に渡します。
その部分関数によって返されたタプル (Double、Double) は、これによって生成されたものにチャネル化されます。
(JsPath \ "lat").write[Double] および (JsPath \ "long").write[Double]
その「なんでも」って具体的に何?JsPath の API ドキュメントに従うと、OWrites だと思います: https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.json.OWrites
しかし... OWrites に「and」という名前のメソッドがあることがわかりません。この「and」はどこで宣言されていますか?そして、それは何をしますか?「oWrites1 と oWrites2」は「oWrites3」を生成しますか? そして、この「oWrites3」は、タプルを入力として受け取る特別なタイプの OWrites ですか? ... その場合... タプルには、ケース クラス ("lat" と "long") のプロパティの名前に関する情報がありません。では、生成された json 文字列が {"lat": 1, "long": 2} であることをどのように知るのでしょうか?
質問の連続で申し訳ありません。これを明確に理解するのを手伝ってください。ありがとう!
*) https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.json.Writes
更新:
- 関連する質問の追加: Scala/Play の構文と意味! コードサンプル