我正在使用Play框架2.1和Scala 2.10.1,并希望构建一个常规功能,以根据自定义案例类的列表构造JsArray。
private def buildJsArray[T](l: List[T])(result: JsArray): JsArray = {
l match {
case List() => result
case x::xs => buildJsArray(xs)(result :+ Json.toJson(x)) // compiling error here!
}
}
用法:
val applyJsonArray = buildJsArray(List[Apple])(new JsArray())
但是,会引发编译错误:
No Json deserializer found for type T. Try to implement an implicit Writes or Format for this type.
我确实为特定的案例类(即Apple案例类)编写了一个Json反序列化器。
如何推迟编译器在运行时而不是在编译时检查x的类型?
非常感谢!
最佳答案
如何修复错误
您必须像这样向您的方法添加implicit parameter:
def buildJsArray[T](l: List[T])(result: JsArray)(implicit tjs: Writes[T]): JsArray
Json.toJson
方法中有这样的参数。之所以必须添加此参数,是因为只有知道
T
是什么之后,您才知道如何将json
转换为T
。这意味着仅当您调用T
时,您才具有序列化buildJsArray
的方法,并且此参数允许您将此序列化方法传递给buildJsArray
方法。如何构建JSArray
您可以只使用
JsArray
的构造函数。它需要一个Seq[JsValue]
:new JsArray(l.map{Json.toJson(_)})
已有一个
Writes
的implicit Traversable
,因此您不需要自己的方法buildJsArray
,您可以使用参数类型为Json.toJson
的List[T]
方法。添加
您应该看一下collections api。它使您可以编写更具可读性和更短的代码:
def buildJsArray[T](l: List[T])(implicit tjs: Writes[T]): JsArray =
l.foldLeft(new JsArray){ (r, x) => r :+ Json.toJson(x) }
关于scala - Scala类型延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17289493/