我试图避免使用Request
包含可选泛型的泛型,Body
以避免在仅在编写主体时需要泛型时将泛型传递到任何地方,并且还因为在未定义主体时没有类型:
case class Body[A](content: A)(implicit val bodyWritable: BodyWritable[A])
case class Request(url: String, body: Option[Body[_]])
private def executeRequest(request: Request) = {
val wsClient: StandaloneWSClient = ???
val requestWithUrl = wsClient.url(request.url)
request.body.fold(requestWithUrl)(body => requestWithUrl.withBody(body.content)(body.bodyWritable))
}
编译失败:
错误:(20, 90) 类型不匹配;
发现:play.api.libs.ws.BodyWritable[(其他一些)_$1(在价值体中)]
需要:play.api.libs.ws.BodyWritable[_$1(in value body)]
我想知道是否有办法不输入请求。
我在用着 "com.typesafe.play" %% "play-ws-standalone" % "2.0.4"
总之你不能这样做。当涉及通配符时,表达式的类型参数总是与其他的不同,即使它们来自同一个变量。类型 Abody.content
和类型参数 Abody.bodyWritable
被解析为不同的本地匿名类型,即使它们来自同一个变量body
,但 Scala 不知道,因为它们是单独的表达式。
为了解决这个问题,最类型安全的方法(也是推荐的)是给 Request 和 executeRequest 添加类型参数以确保类型被解析为相同的。
您还可以创建一个带有类型参数的本地方法,以确保两个表达式共享相同的泛型类型:
private def executeRequest(request: Request) = {
val wsClient: StandaloneWSClient = ???
val requestWithUrl = wsClient.url(request.url)
def f[A](body: Body[A]) = requestWithUrl.withBody(body.content)(body.bodyWritable)
request.body.fold(requestWithUrl)(body => f(body)) // or shorten to request.body.fold(requestWithUrl)(f)
}
或者,我有时会将调用站点移到声明类型参数的类中,在该类中保证类型参数相同。就像是:
case class Body[A](content: A)(implicit val bodyWritable: BodyWritable[A]) {
def getRequest(req: WSRequest) = req.withBody(content)
}
case class Request(url: String, body: Option[Body[_]])
private def executeRequest(request: Request) = {
val wsClient: StandaloneWSClient = ???
val requestWithUrl = wsClient.url(request.url)
request.body.fold(requestWithUrl)(body => body.getRequest(requestWithUrl))
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句