在Scala泛型类'equals'方法中考虑类型参数...是唯一的方法吗?

时间:2010-07-19 18:27:12

标签: generics scala

给出一个简单的泛型类:

class EqualsQuestion[T]( val value :T )

以下代码解析为“false”似乎是合理的:

val a = new EqualsQuestion[Int]( 5 )
val b = new EqualsQuestion[Long]( 5 )
a == b

(是的,这是一个人为的例子。在我的真实代码中,如果类型参数不同,我希望'=='失败,无论值是否相同,尽管此时我不确定是否有意义尽管如此,它还是让我感到震惊的一个有趣的Scala问题。)

无论如何,我当然无法实现这样的equals()方法:

override def equals( obj :Any ) :Boolean = 
{
    obj match {
        case that :EqualsQuestion[T] => 
                ( this.getClass == that.getClass ) &&  // no help
                this.getClass().isInstance(that) && // no help
                //this.value.getClass == that.value.getClass && // doesn't even compile
                this.value == that.value

        case _ => false
    }
}

问题是类型擦除,我知道:所有编译器在这一点上都知道'T'是一种类型,但它不知道那种类型是什么。所以它无法进行比较。

似乎2.8可以通过清单来解决这个问题,但是......我并不完全相信这个问题How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?

还有其他方法吗?

1 个答案:

答案 0 :(得分:4)

以下函数似乎能够区分a和b:

def same(x: EqualsQuestion[_], y: EqualsQuestion[_]) = {
  x.value.asInstanceOf[AnyRef].getClass == y.value.asInstanceOf[AnyRef].getClass && 
  x.value == y.value
}

请注意,这仅适用于T本身不是通用类型的情况,例如:它不会区分List [Int]和List [Long]。我希望这足够好......