Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Does == default to equals?

Tags:

equality

scala

I'm reading through Programming in Scala. It says:

You can redefine the behavior of == for new types by overriding the equals method, which is always inherited from class Any. The inherited equals, which takes effect unless overridden, is object identity, as is the case in Java. So equals (and with it, ==) is by default the same as eq, but you can change its behavior by overriding the equals method in the classes you define. It is not possible to override == directly, as it is defined as a final method in class Any. That is, Scala treats == as if was defined as follows in class Any:

final def == (that: Any): Boolean = 
  if (null eq this) (null eq that) else (this equals that)

But this isn't jibing with what I'm seeing in scala 2.9.1, where it seems like:

  • == doesn't seem to default to equals
  • I can override == directly (without complaint from the compiler, no override needed).

So it seems to me like either:

  • I'm doing it wrong - this definition of Rational gives

    % scala                                                                   
    Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).
    Type in expressions to have them evaluated.
    Type :help for more information.
    
    scala> Rational(1) == Rational(1)
    res0: Boolean = false
    
    scala> Rational(1) equals Rational(1)
    res1: Boolean = true
    
  • or I'm reading an out of date version of the book, and things have changed.

What's going on?

like image 633
rampion Avatar asked Mar 24 '12 17:03

rampion


People also ask

What does == mean in Scala?

But in Scala, == is testing for value equality. Let's understand with example. Example : Scala.

What is the difference between equals () and == in Scala?

== is a final method, and calls . equals , which is not final. This is radically different than Java, where == is an operator rather than a method and strictly compares reference equality for objects.

How does default equals work in Java?

equals() is a method defined in the Object class thus the default implementation of the . equals() method compares the object references or the memory location where the objects are stored in the heap. Thus by default the . equals() method checks the object by using the “==” operator.


1 Answers

You are making a very understandable mistake--you are trying to write a type-safe equals (i.e. def equals(r: Rational)) instead of a generic equals (i.e. override def equals(a: Any)).

So instead of overriding equals--note that you don't need the override keyword!--you are creating another method by overloading the type parameters, and then having two equals methods, one which takes Rational and one which takes Any. Same thing with ==; only the Any-parameterized method cannot be overridden.

To get the behavior consistent with Java (and the Scala library), you'd need to rewrite equals as something like

override def equals(a: Any) = a match {
  case r: Rational => numer == r.numer && denom == r.demon
  case _ => false
}
like image 59
Rex Kerr Avatar answered Sep 23 '22 14:09

Rex Kerr