繁体   English   中英

Scala忽略泛型类型

[英]Scala ignore generic type

我试图避免使用包含Request的泛型Body的泛型on Request以避免在仅在编写主体时需要泛型时将泛型传递到任何地方,并且还因为未定义主体时没有类型:

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(在值主体中)]

我想知道是否有一种方法可以不键入请求。

我正在使用"com.typesafe.play" %% "play-ws-standalone" % "2.0.4"

简而言之,您不能这样做。 涉及通配符时,表达式的类型参数总是彼此不同,即使它们来自同一变量。 A型body.content和的类型参数body.bodyWritable就被解析成不同的本地匿名类型,即使它们来自同一个变量body ,但斯卡拉不知道,因为它们是独立的表达式。

为了解决这个问题,最安全的方法(也是推荐的方法)是在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)
}

另外,有时我将调用站点移到声明了type参数的类中,在该类中,保证type参数是相同的。 就像是:

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))
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM