从TypeTag的推论

鉴于以下抽象类/特征:

  sealed trait P2pMessage[T] {
    def value(): T
  }

  trait P2pReq[T] extends P2pMessage[T]

  trait P2pResp[T] extends P2pMessage[T]

并给出具体的实施:

case class GetTrainingParamsReq(override val value: String) extends P2pReq[String]

case class GetTrainingParamsResp(override val value: String) extends P2pResp[String]

最后:给定一个使用请求/响应对的客户端接口:

  def request[U: TypeTag, V: TypeTag](req: P2pReq[U]): P2pResp[V]

那么为什么以下不是有效的(不编译):

  def getTrainingParams(clientName: String): GetTrainingParamsResp = {
    val resp = rpc.request(GetTrainingParamsReq(clientName))
    resp
  }

(请参阅屏幕截图了解错误消息)。

在这里输入图像描述

P2pResp[Nothing]的类型为Nothing表示TypeTag推断

 def request[U: TypeTag, V: TypeTag](req: P2pReq[U]): P2pResp[V]

根本不工作。 任何想法为什么 - 以及如何纠正?

更新回应评论:来自这篇文章的通知: def request[U: TypeTag, V: TypeTag](req: P2pReq[U]): P2pResp[V]U应该从request()的输入参数的类型和返回类型的V推断出来。


Scala类型推断从上到下工作。 因此,当类型检查val resp = rpc.request(GetTrainingParamsReq(clientName)) ,编译器不会使用来自下面的信息, resp将用作返回值,并且必须具有类型GetTrainingParamsResp

注释预期类型val resp: P2pResp[String]将允许编译器推断V 但现在它不会编译的原因不同:您只有一个P2pResp[String] ,但需要一个GetTrainingParamsResp 。 注释val resp: GetTrainingParamsResp没有任何意义,因为它是返回类型的子类型,而不是相反的,就像

def foo(): Object = ""
val resp: String = foo()

没有意义。

链接地址: http://www.djcxy.com/p/66209.html

上一篇: Inference From TypeTag's

下一篇: Covariance of a passed function argument