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的推论