Inference From TypeTag's
Given the following abstract classes/traits:
  sealed trait P2pMessage[T] {
    def value(): T
  }
  trait P2pReq[T] extends P2pMessage[T]
  trait P2pResp[T] extends P2pMessage[T]
and given a concrete implementation:
case class GetTrainingParamsReq(override val value: String) extends P2pReq[String]
case class GetTrainingParamsResp(override val value: String) extends P2pResp[String]
And finally: given a client interface that uses a request/response pair:
  def request[U: TypeTag, V: TypeTag](req: P2pReq[U]): P2pResp[V]
Then why would the following not be valid (does not compile):
  def getTrainingParams(clientName: String): GetTrainingParamsResp = {
    val resp = rpc.request(GetTrainingParamsReq(clientName))
    resp
  }
(See screenshot for the error message).

 The type of P2pResp[Nothing] as Nothing indicates the TypeTag inference from  
 def request[U: TypeTag, V: TypeTag](req: P2pReq[U]): P2pResp[V]
is not working at all. Any ideas why - and how to correct it?
 Update Responding to a comment: Notice from this post: def request[U: TypeTag, V: TypeTag](req: P2pReq[U]): P2pResp[V] .  The U should be inferred from the type of the input parameter of the invocation of request() and the V from the return type.  
 Scala type inference works from top to bottom.  So when type-checking val resp = rpc.request(GetTrainingParamsReq(clientName)) , the compiler doesn't use information from below that resp will be used as the return value and must have type GetTrainingParamsResp .  
 Annotating the expected type val resp: P2pResp[String] would allow the compiler to infer V .  But now it won't compile for a different reason: you only have a P2pResp[String] , but need a GetTrainingParamsResp .  And annotating val resp: GetTrainingParamsResp makes no sense because it's a subtype of the return type instead of the opposite, just as  
def foo(): Object = ""
val resp: String = foo()
makes no sense.
链接地址: http://www.djcxy.com/p/66210.html上一篇: Scala类型推断和多个参数列表
下一篇: 从TypeTag的推论
