3

Given a simple generic class:

class EqualsQuestion[T]( val value :T )

it seems reasonable that the following code would resolve to "false":

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

(Yes, it's a contrived example. In my real code I wanted '==' to fail if the type parameters are different, regardless if the values are the same, though at this point I'm not sure that makes sense. Still, it struck me as an interesting Scala question to puzzle through.)

Anyway, I of course haven't been able to implement such an equals() method:

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
    }
}

The issue is type erasure, I know: all the compiler knows at this point is that 'T' is a type, but it has no idea what that type is. So it can't make comparisons.

It seems 2.8 can address this with manifests, but... I'm not quite to point of grokking How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?.

Any other ways around this?

Community
  • 1
  • 1
Rodney Gitzel
  • 2,652
  • 16
  • 23
  • The erasure of EqualsQuestion is what you get from the getClass calls on any of its instances (regardless of what `T` is bound to), so by the time you've matched `obj` to `that: EqualsQuestion[_]` you know that `that.getClass` will be the same as `getClass`. – Randall Schulz Jul 20 '10 at 00:54

1 Answers1

4

The following function seems to be able to distinguish between a and b:

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

Please note that this works only if T isn't a generic type itself, e.g. it wouldn't distinguish List[Int] and List[Long]. I hope that's good enough...

Landei
  • 54,104
  • 13
  • 100
  • 195