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



对于这个函数调用:

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库不太熟悉,不知道如何为I传递任何对象,因为它必须实现隐式的write。(我试着通过i: Writes,但这不起作用)。

这样做:

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

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

语法[A: Writes]告诉Scala,除了常规参数之外,您还需要一个Writes[A]类型的隐式参数。然后将这个隐式传递给对Json.toJson的调用。

可能是这样的:

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

通过这种方式,您可以传递任何A,只要您还为它隐式传递一个Writes实例(一种序列化它的方法)。或者你可以定义一个writesforany(我不确定你怎么能做到这一点,它意味着有一个序列化器为任何可能的对象)并遵循Daniel的回答

最新更新