我正在阅读《Scala 编程》。它说:
您可以重新定义的行为==
通过覆盖新类型equals
方法,始终从类继承Any
。继承的equals
除非被覆盖,否则它是对象标识,就像 Java 中的情况一样。所以equals
(随之而来的是,==
) 默认情况下与eq
,但您可以通过覆盖来更改其行为equals
您定义的类中的方法。无法覆盖==
直接,因为它被定义为类中的最终方法Any
。也就是说,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 https://gist.github.com/2185095 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
或者我正在阅读这本书的过时版本,并且事情已经发生了变化。
这是怎么回事?
你犯了一个非常可以理解的错误——你试图编写一个类型安全的 equals (即def equals(r: Rational)
)而不是通用的等于(即override def equals(a: Any)
).
所以而不是覆盖equals
--请注意,您不需要override
关键字!--您正在通过重载类型参数来创建另一个方法,然后使two等于方法,其中需要Rational
和一个需要Any
。同样的事情与==
;只有Any
- 参数化方法不能被覆盖。
为了获得与 Java(和 Scala 库)一致的行为,您需要将 equals 重写为类似的内容
override def equals(a: Any) = a match {
case r: Rational => numer == r.numer && denom == r.demon
case _ => false
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)