对于这个函数调用:
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的回答