给出一个简单的泛型类:
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?。
还有其他方法吗?
答案 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]。我希望这足够好......