0

私はこの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 _)

次の読み取りを作成します。

  1. 最初に ("reads" メソッドを介して) JsValue が指定されると、"lat" が取得され、続いて "long" が取得されます。これら 2 つからタプル (Double、Double) を作成します。-- https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.json.Reads

  2. そのタプルは、その 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のインスタンスが与えられると、次のようになります:

  1. そのオブジェクトを unlift(Location.unapply) によって生成された部分関数に渡します。

  2. その部分関数によって返されたタプル (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


更新:

4

1 に答える 1

0

疑わしい場合は、逆コンパイルしてください。これは暗黙的な があることを示しておりtoFunctionalBuilderOps、これは FunctionalBuilderOpsandでメソッドがあることを確認できます

于 2015-02-04T20:50:11.720 に答える