Json#arr w/ List[Int] 输入

Json#arr w/ List[Int] Input

看着这个很有帮助answer on encoding a List[A] in the Play JSON library,

我尝试使用 Json#arr:

import play.api.libs.json._

scala> Json.arr( 1, 2, 3 )
res21: play.api.libs.json.JsArray = [1,2,3]

到目前为止一切正常,但如果我有 List[Int]:

scala> Json.arr( List(1,2,3) )
res22: play.api.libs.json.JsArray = [[1,2,3]] // not what I wanted

我试图将 List[Int] 作为 var-args 传递(如果这是正确的术语):

scala> Json.arr( List(1,2,3): _* )
<console>:18: error: type mismatch;
 found   : List[Int]
 required: Seq[play.api.libs.json.Json.JsValueWrapper]
       Json.arr( List(1,2,3): _* )
                     ^

但这没有用。

然后,我尝试创建一个 List[JsValueWrapper],然后通过 var-args 将其传递给 Json#arr:

scala>  List(1,2,3).map(Json.toJsFieldJsValueWrapper)
<console>:18: error: No Json serializer found for type T. Try to implement an implicit Writes or Format for this type.
        List(1,2,3).map(Json.toJsFieldJsValueWrapper)
                             ^

尽管失败了,但以下方法在应用于单个 Int 时有效:

scala> Json.toJsFieldJsValueWrapper(1)
res27: play.api.libs.json.Json.JsValueWrapper = JsValueWrapperImpl(1)

scala> Json.arr(res27)
res28: play.api.libs.json.JsArray = [1]

如何将 List[Int] 传递给 Json.arr 以获得 [1,2,3] 的输出,即由三个 JsNumber 组成的 JsArray

如何只使用 Json.toJson 并转换为 JsArray(如果需要)?

scala> Json.toJson(List(1,2,3)).as[JsArray]
res0: play.api.libs.json.JsArray = [1,2,3]

您可以使用 Json.toJson,验证为 JsArray,或者 return 如果无效则为空:

scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)

scala> Json.toJson(list).validate[JsArray].getOrElse(JsArray())
res6: play.api.libs.json.JsArray = [1,2,3]

您还可以使用 Json.arr:

稍微修改您的 lambda
scala> Json.arr(list.map(Json.toJsFieldJsValueWrapper(_)): _*)
res10: play.api.libs.json.JsArray = [1,2,3]

似乎没有括号,编译器在推断 T 是什么时遇到了麻烦。这是因为编译器试图在 eta 扩展匿名函数之前解析隐式,所以它不知道什么参数将传递给 Json.toJsFieldJsValueWrapperJson.toJsFieldJsValueWrapper(_) 根本不同,因为它扩展到略有不同的 Function1:

 x => Json.toJsFieldJsValueWrapper(x)

这里编译器知道 x 将是一个 Int,所以隐含的 Writes[Int] 被解析。