Play Framework 2.4 Writes[-A] 与 OWrites[-A]、Format[A] 与 OFormat[A]。目的?
Play Framework 2.4 Writes[-A] vs OWrites[-A], Format[A] vs OFormat[A]. Purpose?
PlayFramework Json 库中的 Writes[-A] 和 OWrites[-A] 有什么区别?我使用过 Writes[A] 但我无法弄清楚 OWrites 的目的是什么。同样的问题适用于 Format[A] 与 OFormat[A]。
可以找到源代码here for Writes and here for Formats。我看过它们,但我无法弄清楚它们在用法上的区别。
您通常知道编码器总是会生成一个 JSON 对象(与任意 JSON 值相反)。在类型系统中跟踪这一事实使得使用此类编码器的输出成为可能,而无需跳过通常需要的步骤。
例如,假设我们有一个简单的 class:
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 of making method return types more specific in subclasses, and I've taken a slightly different approach to solving this problem in circe。)
PlayFramework Json 库中的 Writes[-A] 和 OWrites[-A] 有什么区别?我使用过 Writes[A] 但我无法弄清楚 OWrites 的目的是什么。同样的问题适用于 Format[A] 与 OFormat[A]。
可以找到源代码here for Writes and here for Formats。我看过它们,但我无法弄清楚它们在用法上的区别。
您通常知道编码器总是会生成一个 JSON 对象(与任意 JSON 值相反)。在类型系统中跟踪这一事实使得使用此类编码器的输出成为可能,而无需跳过通常需要的步骤。
例如,假设我们有一个简单的 class:
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 of making method return types more specific in subclasses, and I've taken a slightly different approach to solving this problem in circe。)