来自TypeTag的推论

时间:2016-05-16 21:56:56

标签: scala types

给出以下抽象类/特征:

  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
  }

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

enter image description here

P2pResp[Nothing]的{​​{1}}类型表示来自

Nothing推断
TypeTag

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

更新回复评论:来自此帖子的通知: def request[U: TypeTag, V: TypeTag](req: P2pReq[U]): P2pResp[V] def request[U: TypeTag, V: TypeTag](req: P2pReq[U]): P2pResp[V]应该从request()调用的输入参数的类型和返回类型的U中推断出来。

1 个答案:

答案 0 :(得分:0)

Scala类型推断从上到下工作。因此,当类型检查var bulk = db.collection.initializeUnorderedBulOp(); var count = 0; db.collection.find({}, { 'field1': 1 }).snapshot().forEach(function(document) { bulk.find({ '_id': document._id }).updateOne( { '$set': { 'field2': document.field1 } }); count++; if(count%1000 === 0) { // Excecute per 1000 operations and re-init bulk.execute(); bulk = db.collection.initializeUnorderedBulkOp(); } }) // clean up queues if(count > 0) { bulk.execute(); } 时,编译器不会使用下面的信息,val resp = rpc.request(GetTrainingParamsReq(clientName))将用作返回值,并且必须具有类型resp

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

一样
val resp: GetTrainingParamsResp

毫无意义。