PlayFramework Json库中的Writes [-A]和OWrites [-A]有什么区别?我已经使用了Writes [A],但我无法弄清OWrites的目的是什么。同样的问题适用于格式[A]与OFormat [A]。Play Framework 2.4写入[-A] vs OWrites [-A],格式[A] vs OFormat [A]。目的?
源代码可以找到here for Writes和here for Formats。我看过他们,但我无法弄清楚他们的用法上的差异。
PlayFramework Json库中的Writes [-A]和OWrites [-A]有什么区别?我已经使用了Writes [A],但我无法弄清OWrites的目的是什么。同样的问题适用于格式[A]与OFormat [A]。Play Framework 2.4写入[-A] vs OWrites [-A],格式[A] vs OFormat [A]。目的?
源代码可以找到here for Writes和here for Formats。我看过他们,但我无法弄清楚他们的用法上的差异。
通常你知道编码器总是会产生一个JSON对象(而不是任意的JSON值)。在类型系统中跟踪这个事实使得可以使用这样的编码器的输出来工作,而不用跳过通常是必需的环。
例如,假设我们有一个简单的类:
class Foo(val name: String, val age: Long)
我们写一个Writes
情况是这样的:
import play.api.libs.functional.syntax._
import play.api.libs.json._
implicit val fooWrites: Writes[Foo] = (
(__ \ 'name).write[String] and (__ \ 'age).write[Long]
)(foo => (foo.name, foo.age))
现在我们可以写:
scala> val json = fooWrites.writes(new Foo("McBar", 101))
json: play.api.libs.json.JsValue = {"name":"McBar","age":101}
现在假设我们想要得到一个字段名称列表,无论出于何种原因。我们必须写这样的事:
scala> json.as[JsObject].keys
res0: scala.collection.Set[String] = Set(name, age)
取而代之的是:
scala> json.keys
<console>:17: error: value keys is not a member of play.api.libs.json.JsValue
json.keys
^
但当然我们知道json
将永远是一个JsObject
。问题是编译器没有。 OWrites
解决了这个问题。
implicit val fooWrites: OWrites[Foo] = (
(__ \ 'name).write[String] and (__ \ 'age).write[Long]
)(foo => (foo.name, foo.age))
然后:
scala> val json = fooWrites.writes(new Foo("McBar", 101))
json: play.api.libs.json.JsObject = {"name":"McBar","age":101}
scala> json.keys
res1: scala.collection.Set[String] = Set(name, age)
的writes
上OWrites
输出静态类型为JsObject
,所以我们可以使用.keys
没有不安全as[JsObject]
演员。
(作为一个方面说明,我制作方法的返回类型的子类更具体的not personally a fan,我已经采取了a slightly different approach在circe解决这个问题。)
所以,你说的是,如果我知道某个东西是Json对象(而不是Json数组)比实现一个OWrites而不是一个Writes更好,对吧?关于“不是个人粉丝”中的链接,我无法在任何地方找到“更具体的返回类型”,所以我无法得到这个想法。你能解释一下你连接的问题吗?感谢OWrites的解释:) – vicaba
如果您的用例需要它,则更为可取。我不知道'OWriter'是否给你比普通的'Writer'更多/不同的功能,除了你在编译时知道它是一个JsObject。我认为@Travis所说的“更具体的返回类型”是指'OWrites [T]扩展Writes [T]'其中'Writest [T]''def写入(in:T):JsValue',而同样的方法在'OWrites [T]'是'def writes(in:T):JsObject',其中'JsObject'是'JsValue'的子类。 – goral
@goral是的,我在Writes和OWrites的例子中看到了这个想法,但是我不明白的是这里发生了什么:http:// stackoverflow。com/questions/31080332/why-is-upcasting-necessary-in-this-scala-code#comment50187425_31080332 – vicaba