scala - Scala类型延迟

标签 scala playframework-2.0

我正在使用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(_)})

已有一个Writesimplicit Traversable ,因此您不需要自己的方法buildJsArray,您可以使用参数类型为Json.toJsonList[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/

相关文章:

java - Java Play Framework 2 中的路由,List<> 作为参数

java - Playframework 2 和 Manytoone 表单绑定(bind)

scala - Play 2.0 中的子域

scala - playframework2 jquery 错误 (jquery.min.map)

list - 是否可以重载接受 Scala 列表的构造函数?

java - Play 框架应用程序中的内存泄漏

scala - 如何在scala中将字符串与方法结果匹配?

scala - 具有 ADT 和 Aux 模式的类型安全

java - 玩java 2.5 guice急切加载并停止钩子(Hook)不工作

java - 玩 SecureSocial 定制