简体   繁体   中英

Scala: Does == default to equals?

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?

You are making a very understandable mistake--you are trying to write a type-safe equals (ie def equals(r: Rational) ) instead of a generic equals (ie 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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM