Çoğu zaman bir kodlayıcının her zaman bir JSON nesnesini (isteğe bağlı bir JSON değerinin aksine) üreteceğini biliyorsunuzdur. Bu gerçeği tip sistemde izlemek, normalde gerekli olacak olan çemberler içinden atlamaksızın böyle bir kodlayıcının çıktısı ile çalışmayı mümkün kılar.
Örneğin, elimizdeki basit bir sınıfı varsayalım:
class Foo(val name: String, val age: Long)
Ve böyle bir Writes
örneği yazma:
scala> val json = fooWrites.writes(new Foo("McBar", 101))
json: play.api.libs.json.JsValue = {"name":"McBar","age":101}
:
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))
Şimdi aşağıdaki yazabilirsiniz
Şimdi hangi sebepten dolayı alan adlarının bir listesini almak istediğimizi varsayalım. Bunun yerine
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
^
Ama tabii biz json
daima JsObject
olacağını biliyoruz Biz böyle bir şey yazmak zorunda. Sorun derleyici değil. OWrites
bunu düzeltir.
implicit val fooWrites: OWrites[Foo] = (
(__ \ 'name).write[String] and (__ \ 'age).write[Long]
)(foo => (foo.name, foo.age))
Ve sonra:
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)
OWrites
üzerinde writes
çıkışı statik bir JsObject
olarak yazıldığında, bu yüzden güvensiz as[JsObject]
döküm olmadan .keys
kullanabilirsiniz.
(Bir yan not olarak, alt sınıflar yöntem dönüş tipleri daha spesifik yapma
not personally a fan değilim, ben
circe bu sorunu çözmek için
a slightly different approach attık.)
Ee, ne diyorsun olması durumunda Biliyorum ki bir şey bir Json Nesnesi (bir Json Array'ın aksine), bir Write yerine bir OWrites'i uygulamak için tercih edilir, doğru mu? Ve "şahsen bir fan değil" bağlantısına ilişkin olarak, "daha spesifik dönüş türünü" her yerde bulamıyorum. Fikri alamıyorum. Bağlandığınız problem hakkında biraz daha açıklayabilir misiniz? OWrites açıklaması için teşekkürler :) – vicaba
Kullanım çantanız gerektiriyorsa daha çok tercih edilir. OWriter'in, derleme zamanında bildiğiniz gerçeğin dışında, “Yazar” dan daha fazla/farklı güç sağlayıp sağlamadığını bilmiyorum, bu bir JsObject. @Travis'in "daha spesifik dönüş tipi" ile kastettiğini düşünüyorum, OWrites [T], Writest [T] ''nin yazısını yazdığı (T: T: JsValue) yazarken [T] Writes [T]' yi uzatır. 'OWrites [T] '', def yazıyor (in: T): JsObject' 'JsObject'' JsValue'nin alt sınıfıdır. – goral
@goral Evet, Writes vs OWrites örneğinde bu fikri yakaladım ama anlamadığım şey burada olan şey: http: // stackoverflow.com/questions/31080332/neden-is-upcasting-gerekli-in-bu-scala-kod # comment50187425_31080332 – vicaba