0

我一直在将这个 json 组合器用于几个基本/标准案例,但并没有真正理解它是如何工作的。一切都很好。

现在我想让自己为可能出现的任何高级案例做好准备;我需要理解代码。

参考:https ://www.playframework.com/documentation/2.3.x/ScalaJsonCombinators

我想我可以理解阅读:

implicit val locationReads: Reads[Location] = (
  (JsPath \ "lat").read[Double] and
  (JsPath \ "long").read[Double]
)(Location.apply _)

它创建一个读取:

  1. 首先——当给定一个 JsValue(通过它的“reads”方法)——它拉取“lat”,然后是“long”。在这两者中,它创建了一个元组(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 步,我们得到一个 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”的方法。这个“和”在哪里声明?它有什么作用?是:“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的,然后您可以在 FunctionalBuilderOps中看到您的and方法

于 2015-02-04T20:50:11.720 回答