2015-08-29 13 views

cevap

19

Ç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.)

+0

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

+1

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

+0

@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

İlgili konular