从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