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