【发布时间】:2013-08-31 00:30:06
【问题描述】:
在scala.Any的scaladoc中,解释了操作符==(或者,方法==):
表达式
x == that等价于if (x eq null) that eq null else x.equals(that)http://www.scala-lang.org/api/current/#scala.Any
对于AnyRef的子类的对象,我很容易理解,也没有看到什么奇怪的东西。
但是,对于 AnyVal 的值,(我的意思是 Int、Double、Long 等等),上面的定义有点棘手(1 eq null?如果我们这样做,这不会编译不将 1 转换为 java.lang.Integer)。此外,== 和 equals() 的行为也不同。
我会举一些例子。
斯卡拉> 1 == 1 res0: 布尔 = 真 斯卡拉> 1 == 1.0 res1:布尔=真 斯卡拉> 1 == 1.2 res2: 布尔 = 假 scala> 2 == BigInt(2) res3: 布尔 = 真 scala> 2.0 == BigInt(2) res4:布尔=真 scala> 2 == BigInt(3) res5: 布尔 = 假到目前为止,没有什么是奇怪的。但是如果我们用equals() 方法做同样的事情,
所以如果类型不同,equals() 总是返回 false,而 == 测试它们是否表示相同的值,如果它们被转换为相同的类型。
对于AnyRef 的子类,方法== 和equals() 返回相同。
那么,为什么 == 和 equals() 方法与 AnyVal 不同?
我使用的是 Scala 版本 2.10.2(Java HotSpot(TM) 64 位服务器 VM,Java 1.7.0_25)。
编辑 1
我看到 == 不能被直接覆盖,因为它根据Programming in Scala, 2nd Edition 定义为 Any 类中的最终方法。
编辑 2
虽然有答案,但我的问题仍然存在。我将保留这个问题。
Java中的scala.Int和scala.Long对应的是Java的基本类型int和long。
在Java中,java.lang.Integer和java.lang.Long是类,所以它们的变量是引用,可以有null。
这意味着,它们就像 Scala 中的AnyRef。不是AnyVal。
Scala 的 AnyVal - scala.Int 和 scala.Long 不能有 null 值,Java 的 int 和 long 也不能。
此外,Java 中的 java.lang.Integer 的 == 用于引用相等(与 Scala 中的 eq 相同)。
在这方面,您在 Scala REPL 中使用 java.lang.Integer 所获得的结果将与在带有 .java 源文件的纯 Java 项目中获得的结果完全不同。
但是,在 Java 中使用原始类型类可以得到:(这是 JAVA)
class Main {
public static void main(String[] args) {
System.out.println(String.valueOf(new java.lang.Integer(1).equals(1)));
System.out.println(String.valueOf(new java.lang.Integer(1).equals(1L)));
System.out.println(String.valueOf(new java.lang.Integer(1).equals(1.0)));
System.out.println(String.valueOf(new java.lang.Integer(1).equals(new java.lang.Integer(1))));
System.out.println(String.valueOf(new java.lang.Integer(1).equals(new java.lang.Long(1))));
}
}
输出:
equals()。但是,那么,为什么会发生这种情况呢?
Scala 的AnyVal 的== 是否对应Java 原始类型的==
Scala 的 AnyVal 的 equals() 是否对应于 Java 类类型的 equals()?
BigInt 的相等性测试怎么样? Java中没有对应的原始类型。
问题仍然存在......
编辑 3
我可以从 scaladoc 中找到一些信息。 (http://www.scala-lang.org/api/current/index.html#scala.Int)
来自Shadowed Implicit Value Members项的隐含信息,
我可以发现== 被Char、Short、Float 和...重载,
而== 将调用隐式转换int2double、int2float 或int2long。
而equals() 只为Any 定义,它会调用隐式转换int2Integer。
也就是说,Int.equals() 将与 java.lang.Integer.equals() 相同。
还有一个问题:
为什么AnyVal的==会超载,而AnyVal的equals()不会超载?
【问题讨论】:
-
我很抱歉,但我在整个帖子之后感到困惑。您能否在最后指定确切的问题是什么?
-
@Jatin
==和equals()方法在 Scala 中的AnyRef值中是相同的。我认为AnyVal值也应该相同。事实上,它们是不同的。但是,我在学习 Scala 时找不到任何相关信息。那么,为什么==和equals()对于AnyVal不一样呢?有没有这方面的规范? -
@Naetmul,这个输出怎么样:`println(Double.NaN == Double.NaN) println(Double.NaN equals Double.NaN)',我期待的是真的,但输出是假的真的,不明白,任何帮助将不胜感激!!!
标签: scala equals equality primitive