Scala类型推迟

时间:2013-06-25 05:05:21

标签: scala playframework-2.0

我正在使用Play framework 2.1和Scala 2.10.1,并希望构建一个通用函数来从自定义案例类的List中构造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的类型?

非常感谢!

1 个答案:

答案 0 :(得分:15)

如何修复错误

您必须在方法中添加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(_)})

Traversable已有implicit Writes,因此您不需要自己的方法buildJsArray,只需使用类型为{{1的参数的方法Json.toJson即可}}

<强>加成

你应该看看集合api。它允许您编写更易读和更短的代码:

List[T]