具有相同类型的局部变量(泛型类型参数)具有不兼容的类型

时间:2016-01-29 13:53:09

标签: scala generics

此问题与另一个issue

中描述的编译器行为有关

我认为这与编译器中泛型的实现方式有关,它与内部类编译器功能有关。我有一个类似的问题,我知道这可以通过

解决
if(m.compare(lowerBound.asInstanceOf[m.Measure]) >= 0) {

但我不想在我的代码中将相同类型转换为相同类型。应该有很好的解释为什么会这样。我应该在某处填写编译器错误吗? 没有局部变量m - 错误消息变得更加奇怪。

trait MeasureBase {
  type Measure <: MeasureBase
  def compare(that: Measure): Int
  def score: Double
}
case class DocTerm[Measure <: MeasureBase]
(val docID: Long, val measure:Measure)
  extends Ordered[DocTerm[Measure]] {
  def score = measure.score
  def compare(that: DocTerm[Measure]): Int
  = measure.compare(that.measure.asInstanceOf[measure.Measure])
}

   class WriteCacheIterator[Measure <: MeasureBase]
    (data:mutable.ArrayBuffer[DocTerm[Measure]]) {
      var position = 0
      def Next(lowerBound:Measure):Option[DocTerm[Measure]] = {
        if(position < data.size - 1){
          val m:Measure = data(position).measure
          val b:Measure = lowerBound
          if(m.compare(b) >= 0) {
            //gives compiler error 
            //Error:(39, 20) type mismatch;
            //found   : b.type (with underlying type Measure)
            //required: m.Measure
            //if(m.compare(b) >= 0) {
          }
        } else return None
      }
    }

1 个答案:

答案 0 :(得分:2)

Measure有两种不同的定义:

  • DocTerm和其他地方的类型参数,它是MeasureBase的子类型。
  • MeasureBase内的类型成员。

两者没有任何共同之处(除了名称,但它们确实是不同的东西)。在Measure中的每个元素中,WriteCacheIterator内的Measure通用ArrayBuffertrait MeasureBase[Self <: MeasureBase[Self]] {...} case class DocTerm[M <: MeasureBase[M](val docID: Long, val measure: M) ... 内的类型成员无关。您需要重构代码以使此约束显式化。

你可能可以重构代码,只在每个地方使用类型参数(泛型)。

draggable