ari*_*ris 7 polymorphism scala playframework-2.1
我想为包含基类和派生类的List生成JSON.下面的代码只为Animal类生成JSON(我没有得到Dog类型成员的品种字段).一些帮助将不胜感激.
import play.api.libs.json._
class Animal (val name:String) {
}
object Animal {
implicit object animalWrite extends Writes[Animal] {
def writes(ts: Animal) = JsObject(Seq("name" -> JsString(ts.name)))
}
}
case class Dog (override val name:String, val breed: String)
extends Animal(name) {
}
object Dog {
implicit val format = Json.format[Dog]
}
case class Cat (override val name:String, val hairLength: Int)
extends Animal(name) {
}
object Cat {
implicit val format = Json.format[Cat]
}
object helloWorld extends App {
// The list below outputs: [{"name":"Ruff","breed":"labrador"}]
// val l = List[Dog](Dog("Ruff", "labrador"))
// The list below outputs: [{"name":"Ruff"},{"name":"Fluffy"}]
// I expect to see: [{"name":"Ruff","breed":"labrador"},{"name":"Fluffy","hairLength":3}]
val l = List[Animal](Dog("Ruff", "labrador"), Cat("Fluffy", 3))
println(Json.toJson(l))
}
Run Code Online (Sandbox Code Playgroud)
Scala和Play新手在这里,请原谅不当使用的术语.
json API广泛使用隐式参数,这是Scala的一个特性,您可以在其中提供"隐式"参数列表,如果您不指定这些参数,编译器将尝试在当前作用域中找到标记为隐式的对象.匹配该签名.
所以,如果您举例如下:
implicit val s = "my implicit string"
def magicPrint(implicit message: String) { println(message) }
// and then call it
magicPrint
Run Code Online (Sandbox Code Playgroud)
编译器会为参数消息选择s,因为它在范围内并且具有正确的type(String),因此在隐式解析之后,最后一行代码实际上看起来更像是这样
magicPrint(s)
Run Code Online (Sandbox Code Playgroud)
编译器在编译时使用隐式参数选择格式/编写器.如果你看一下方法的签名toJson[A](item: A)(implicit writes: Writes[A]),那么它就是一个隐含的Writes[A],在你的情况下是一个,Writes[List[Animal]]因为List[Animal]是你的列表的类型l.Play包含一个默认具有一个编写器,它负责处理collection(DefaultWrites.traversableWrites),而collection 又采用隐式Writes[A]- 在你的情况下Writes[Animal],编译器将选择并传递你的animalWrites.
您的列表包含不同类型的动物是在运行时发生的事情,编译器无法从您可用的类型信息中获知 Json.toJson(l)
所以,正如你所看到的那样,你无法以你想象的方式实现你想要的东西,但是你可以通过让动物作家了解子类型来以几乎相同的方式实现它,例如:
implicit object animalWrite extends Writes[Animal] {
def writes(ts: Animal) = ts match {
// this will get an implicit Writes[Dog] since d is a Dog
case d: Dog => Json.toJson(d)
// this will get an implicit Writes[Cat] since c is a Cat
case c: Cat => Json.toJson(c)
case x => throw new RuntimeException(s"Unknown animal $x")
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有帮助!
| 归档时间: |
|
| 查看次数: |
1534 次 |
| 最近记录: |