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