我试图通过在它周围编写包装来在Scala中使用外部Java Service API。每个API调用都有一个Request类和Response类,以及在底层java客户端中设置调用的工厂方法,即
val caller = serviceClient.newDoSomething()
val request = DoSomethingRequest(...)
val response = caller.call(request)
其中响应的类型为DoSomethingResponse
。
对于一组不同的操作重复此模式,这些操作仅在请求/响应类和工厂方法的名称中有所不同。我想干掉代码并使用类型推断,同时注意到java方法的关键观察
caller.call
的类型为Request => Response
。
鉴于我已尝试以下方法:
class ServiceAPI {
val client = Service.getDefaultClient
def serviceCall[Req, Resp](auth: String, caller: Req => Resp)
(func: Req => Unit)(implicit m:Manifest[Req]):Resp = {
val request = m.erasure.newInstance.asInstanceOf[Req]
request.setAuth(auth)
func(request)
caller(request)
}
}
我最终想要的是一个可消费的scala API,可以像这样调用:
serviceCall(myAuth, client.newEventCall.call(_)) {
_.setFoo("foo") // On request
_.setBar(2) // On request
}
我希望通过提供部分函数client.newEventCall.call(_)
,Scala能够从中完全推断Req
和Resp
,然后正确地调用其余部分。
然而,这失败了:
error: missing parameter type for expanded function ((x$4) => client.newEventCall.call(x$4))
显然我可以通过以下方式手动提供类型:
serviceCall(myAuth, client.newEventCall.call(_:EventRequest)) { ... }
但我想避免这种情况。有什么想法吗?
如果可以进一步简化,也可以获得奖励。