我一直在将这个 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 _)
它创建一个读取:
首先——当给定一个 JsValue(通过它的“reads”方法)——它拉取“lat”,然后是“long”。在这两者中,它创建了一个元组(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 步,我们得到一个 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”的方法。这个“和”在哪里声明?它有什么作用?是:“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 的语法和含义!代码示例