繁体   English   中英

Scala:==默认为等于?

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

我正在阅读Scala编程。 它说:

您可以通过重写equals方法重新定义==对新类型的行为,该方法始终从Any类继承。 除非被覆盖,否则继承的equals是对象标识,就像Java中的情况一样。 因此, equals (和它, == )默认与eq相同,但您可以通过覆盖您定义的类中的equals方法来更改其行为。 不能直接覆盖== ,因为它被定义为Any类中的final方法。 也就是说,Scala将==视为在Any类中定义如下:

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

但这并不是我在scala 2.9.1中看到的内容,它看起来像:

  • ==似乎没有默认为equals
  • 我可以直接覆盖== (没有来自编译器的抱怨,不需要override )。

所以在我看来似乎要么:

  • 我错了,这样做- 这个定义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 
  • 或者我正在阅读这本书的过时版本,事情已经发生了变化。

这是怎么回事?

您正在犯一个非常容易理解的错误 - 您正在尝试编写类型安全等于(即def equals(r: Rational) )而不是通用等于(即override def equals(a: Any) )。

因此,不要覆盖equals - 不需要override关键字! - 您通过重载类型参数创建另一个方法,然后使用两个 equals方法,一个接受Rational ,另一个接受Any 同样的事情== ; 只有Any -parameterized方法不能被覆盖。

要获得与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