ScalaJsonCombinator 中的 "and" 是什么(定义 Writes 时)?
What is this "and" in ScalaJsonCombinator (when defining a Writes)?
我一直在几个基本/标准案例中使用这个 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... 的部分函数,在本例中是 return 由 "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 的实例作为 "reads".
的 return
现在开始写作:
implicit val locationWrites: Writes[Location] = (
(JsPath \ "lat").write[Double] and
(JsPath \ "long").write[Double]
)(unlift(Location.unapply))
首先是"unapply"。我在回复中试过:
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) 的(可选)元组。
接下来,"unlift":
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 简单地扔掉 "Option",直接把我们带到元组。
好的...所以...我猜...这个 "writes" 的 Writes... *) 当给定 Location 的实例时,它将:
通过 unlift(Location.unapply) 生成的部分函数传递该对象。
由该部分函数编辑的元组 (Double, Double) return 然后被引导到由此产生的任何东西:
(JsPath \ "lat").write[Double] 和
(JsPath \"long").write[Double]
那 "whatever" 到底是什么?按照 JsPath 的 API 文档,我认为它是 OWrites: https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.json.OWrites
但是...我看不到 OWrites 中有一个名为 "and" 的方法。 "and" 在哪里声明?它有什么作用?是:"oWrites1 and oWrites2" 产生 "oWrites3"?而这个 "oWrites3" 是一种特殊类型的 OWrites,它以元组为输入? ...如果是这种情况...在 class("lat" 和 "long")的情况下,元组没有关于 属性 名称的信息。它怎么知道生成的 json 字符串应该是 {"lat": 1, "long": 2} 那么?
抱歉提出了一系列问题。请帮助我清楚地了解这一点。谢谢!
*) https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.json.Writes
更新:
- 添加相关问题:Syntax and meaning of a Scala/Play! code sample
如有疑问,请反编译。这表明有一个隐含的 toFunctionalBuilderOps
,然后 you can see in FunctionalBuilderOps 有你的 and
方法
我一直在几个基本/标准案例中使用这个 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... 的部分函数,在本例中是 return 由 "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 的实例作为 "reads".
的 return现在开始写作:
implicit val locationWrites: Writes[Location] = (
(JsPath \ "lat").write[Double] and
(JsPath \ "long").write[Double]
)(unlift(Location.unapply))
首先是"unapply"。我在回复中试过:
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) 的(可选)元组。
接下来,"unlift":
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 简单地扔掉 "Option",直接把我们带到元组。
好的...所以...我猜...这个 "writes" 的 Writes... *) 当给定 Location 的实例时,它将:
通过 unlift(Location.unapply) 生成的部分函数传递该对象。
由该部分函数编辑的元组 (Double, Double) return 然后被引导到由此产生的任何东西:
(JsPath \ "lat").write[Double] 和 (JsPath \"long").write[Double]
那 "whatever" 到底是什么?按照 JsPath 的 API 文档,我认为它是 OWrites: https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.json.OWrites
但是...我看不到 OWrites 中有一个名为 "and" 的方法。 "and" 在哪里声明?它有什么作用?是:"oWrites1 and oWrites2" 产生 "oWrites3"?而这个 "oWrites3" 是一种特殊类型的 OWrites,它以元组为输入? ...如果是这种情况...在 class("lat" 和 "long")的情况下,元组没有关于 属性 名称的信息。它怎么知道生成的 json 字符串应该是 {"lat": 1, "long": 2} 那么?
抱歉提出了一系列问题。请帮助我清楚地了解这一点。谢谢!
*) https://www.playframework.com/documentation/2.3.x/api/scala/index.html#play.api.libs.json.Writes
更新:
- 添加相关问题:Syntax and meaning of a Scala/Play! code sample
如有疑问,请反编译。这表明有一个隐含的 toFunctionalBuilderOps
,然后 you can see in FunctionalBuilderOps 有你的 and
方法