如何在Scala中传递任何对象作为Json可写?

时间:2015-05-17 03:27:53

标签: json scala

对于此函数调用:

fakeRequest(controllers.routes.GPInviteService.invite, Json.toJson(i))

定义为:

def fakeRequest(target: () => Call, json: JsValue): Any

我想简化调用代码,并且不需要创建Json对象。所以,电话会变成:

fakeRequest(controllers.routes.GPInviteService.invite, i)

然后该功能将成为:

def fakeRequest(target: () => Call, i: Any): Any = {
    route(FakeRequest(target()).withJsonBody(Json.toJson(i))) match {
                                                         ^
    ...

但是这会给我一个编译错误,因为toJson()想要一个Writes [A]类型。我对Scala和Json库不太熟悉,因为它必须实现一个隐式的Writes,所以我可以弄清楚如何为i传递任何对象。 (我尝试传递i: Writes,但这不起作用。)

2 个答案:

答案 0 :(得分:1)

这样做:

def fakeRequest[A: Writes](target: () => Call, i: A): Any = {

对于类型为Json.toJson的参数,对Writes[A]的函数调用根据错误消息采用类型为A的隐式参数。最重要的是,这意味着您无法传递Any - 必须必须在调用方法时静态知道,Writes[A]在运行时提供该信息(因为类型参数被删除了。)

语法[A: Writes]告诉Scala除了普通参数外,还需要类型为Writes[A]的隐式参数。然后,这隐含的内容将被传递给Json.toJson的调用。

答案 1 :(得分:1)

可能是这样的:

def fakeRequest[A](target: () => Call, i: A)(implicit writes: Writes[A]): A = { ...

这样你可以传递任何A,前提是你也为它隐式传递了一个Writes实例(一种序列化它的方法)。或者你可以定义一个Writes for Any(我不知道你怎么做,它意味着为任何可能的对象设置一个序列化器)并遵循Daniel的回答