我有一个如下所示的案例类:
案例类 A(名称:String,值:List[Any]) 而值可以是长列表或字符串。
我正在尝试实现写入但没有成功。 这是我的代码:
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))
出于某种原因,当我尝试使用以下值编写案例类时:
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
通常是一个好主意。
关于json - 玩 - 尝试实现写入列表[任何],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35834218/