简体   繁体   English

Scala:==默认为等于?

[英]Scala: Does == default to equals?

I'm reading through Programming in Scala. 我正在阅读Scala编程。 It says: 它说:

You can redefine the behavior of == for new types by overriding the equals method, which is always inherited from class Any . 您可以通过重写equals方法重新定义==对新类型的行为,该方法始终从Any类继承。 The inherited equals , which takes effect unless overridden, is object identity, as is the case in Java. 除非被覆盖,否则继承的equals是对象标识,就像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. 因此, equals (和它, == )默认与eq相同,但您可以通过覆盖您定义的类中的equals方法来更改其行为。 It is not possible to override == directly, as it is defined as a final method in class Any . 不能直接覆盖== ,因为它被定义为Any类中的final方法。 That is, Scala treats == as if was defined as follows in class Any : 也就是说,Scala将==视为在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: 但这并不是我在scala 2.9.1中看到的内容,它看起来像:

  • == doesn't seem to default to equals ==似乎没有默认为equals
  • I can override == directly (without complaint from the compiler, no override needed). 我可以直接覆盖== (没有来自编译器的抱怨,不需要override )。

So it seems to me like either: 所以在我看来似乎要么:

  • I'm doing it wrong - this definition of Rational gives 我错了,这样做- 这个定义Rational给出

     % 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) ). 您正在犯一个非常容易理解的错误 - 您正在尝试编写类型安全等于(即def equals(r: Rational) )而不是通用等于(即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 . 因此,不要覆盖equals - 不需要override关键字! - 您通过重载类型参数创建另一个方法,然后使用两个 equals方法,一个接受Rational ,另一个接受Any Same thing with == ; 同样的事情== ; only the Any -parameterized method cannot be overridden. 只有Any -parameterized方法不能被覆盖。

To get the behavior consistent with Java (and the Scala library), you'd need to rewrite equals as something like 要获得与Java(和Scala库)一致的行为,您需要将equals重写为类似的东西

override def equals(a: Any) = a match {
  case r: Rational => numer == r.numer && denom == r.demon
  case _ => false
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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