Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 播放-尝试实现写入列表[任何]_Json_Scala_Playframework_Playframework 2.0 - Fatal编程技术网

Json 播放-尝试实现写入列表[任何]

Json 播放-尝试实现写入列表[任何],json,scala,playframework,playframework-2.0,Json,Scala,Playframework,Playframework 2.0,我有一个case类,如下所示: 案例类别A(名称:字符串,值:列表[任何]) 而值可以是长字符串或字符串的列表 我正在尝试实现一个写操作,但没有成功。 这是我的代码: implicit val myWrites: Writes[A] = ( (JsPath \ "name").write[String] and (JsPath \ "values").write[JsArray].contramap[List[Any]]( (list: List[Any]) => list m

我有一个case类,如下所示:

案例类别A(名称:字符串,值:列表[任何]) 而值可以是长字符串或字符串的列表

我正在尝试实现一个写操作,但没有成功。 这是我的代码:

implicit val myWrites: Writes[A] = (
(JsPath \ "name").write[String] and
  (JsPath \ "values").write[JsArray].contramap[List[Any]](
    (list: List[Any]) => list match{
    case longs: List[Long] => JsArray(longs.map(l => JsNumber(l)))
    case strings: List[String] => JsArray(strings.map(s => JsString(s)))
  })
) (unlift(A.unapply))
出于某种原因,当我试图用以下值编写case类时:

A("name", List("val1", "val2"))
我得到以下例外情况:

java.lang.String cannot be cast to java.lang.Long
java.lang.ClassCastException: java.lang.String cannot be cast to                             
java.lang.Long
at scala.runtime.BoxesRunTime.unboxToLong(BoxesRunTime.java:105)
它在第一个case行失败:case longs:List[Long]

我不确定我做错了什么。有什么想法吗


谢谢

非常接近,但请记住,当您说
List[Any]
时,就类型系统而言,列表值可能是异构的,正如@m-z指出的,泛型类型将被删除

在这种情况下,我会使用
collect
List[Any]
转换为
List[JsValue]
以丢弃任何不是字符串或长字符串的内容:

case class A(name: String, values: List[Any])

implicit val myWrites: Writes[A] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "values").write[List[JsValue]].contramap[List[Any]](
    _.collect {
      case str: String => JsString(str)
      case long: Long => JsNumber(long)
    })
)(unlift(A.unapply))

我最近不得不做一些类似的事情来处理一个接受异构JSON数组的web服务,但通常最好避免在Scala级别使用
Any

对解决方案的另一个建议:

implicit val myWrites: Writes[A] = (
(JsPath \ "name").write[String] and
  (JsPath \ "values").write[JsArray].contramap[List[Any]](
    case l if l.isEmpty => JsArray(Seq())
    case list@List(_: Long, _*) => JsArray(list.map(l => JsNumber(l.asInstanceOf[Long])))
    case list@List(_: String, _*) => JsArray(list.map(s => JsString(s.asInstanceOf[String])))
) (unlift(A.unapply))

List
的类型参数在运行时被删除,因此无论包含的类型是什么,
longs:List[Long]
都将匹配。为什么您需要一个
列表[Any]
?注意这一点,因为如果您的列表同时包含字符串和long(类型系统将允许),它将在运行时失败,出现
ClassCastException
。同意-我假设同一列表中不会有多个类型。