给出以下抽象类/特征:
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]
的{{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
中推断出来。
答案 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
毫无意义。