Scala类型延迟 [英] Scala type deferring

查看:68
本文介绍了Scala类型延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Play框架2.1和Scala 2.10.1,并想构建一个通用函数来从自定义案例类列表中构造JsArray.

I am using Play framework 2.1 and Scala 2.10.1 and would like to build a general function to construct a JsArray out of a List of custom case class.

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())

但是,会引发编译错误:

However, a compiling error is thrown:

No Json deserializer found for type T. Try to implement an implicit Writes or Format for this 
 type.

我确实为特定案例类别(即Apple案例类别)编写了一个Json反序列化器.

I do have a Json deserializer written for the particular case class(i.e., Apple case class).

如何推迟编译器在运行时而不是在编译时检查x的类型?

How do I defer the compiler to check the type of x in runtime rather than in compile time?

非常感谢!

推荐答案

如何解决错误

您必须在方法中添加隐式参数像这样:

You have to add an implicit parameter to your method like this:

def buildJsArray[T](l: List[T])(result: JsArray)(implicit tjs: Writes[T]): JsArray

之所以必须添加此参数,是因为只有知道T是什么之后,您才知道如何将T转换为json.这意味着仅当调用buildJsArray时,您才具有序列化T的方法,并且此参数允许您将此序列化方法传递给方法buildJsArray.

The reason why you have to add this parameter is that you know how to convert T to json only when you know what T is. It means you have the method to serialize T only when you call buildJsArray and this parameter allows you to pass this serialization method to the method buildJsArray.

如何构建JSArray

您可以只使用 JsArray .需要Seq[JsValue]:

new JsArray(l.map{Json.toJson(_)})

已经有一个

There is already an implicit Writes for Traversable so you don't need your own method buildJsArray, you could just use method Json.toJson with parameter of type List[T].

添加

您应该看一下collections api.它使您可以编写更具可读性和更短的代码:

You should take a look at the collections api. It allows you to write more readable and shorter code:

def buildJsArray[T](l: List[T])(implicit tjs: Writes[T]): JsArray =
  l.foldLeft(new JsArray){ (r, x) => r :+ Json.toJson(x) }

这篇关于Scala类型延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆