Im scaladoc von scala.Any
der Betreiber ==
(oder Methode ==
) erklärt:Warum Operator == und equals() verhalten sich anders für Werte von AnyVal in Scala
The expression
x == that
is equivalent toif (x eq null) that eq null else x.equals(that)
http://www.scala-lang.org/api/current/#scala.Any
Für Objekte von Subklassen von AnyRef
Ich kann es leicht verstehen, und ich habe keine merkwürdigen Dinge gesehen.
jedoch für Werte von AnyVal
, (ich meine Int
, Double
, Long
, und so weiter,) die obige Definition etwas schwierig ist (1 eq null
? Diese nicht kompiliert, wenn wir 1
konvertieren nicht zu java.lang.Integer). Auch ==
und equals()
verhalten sich anders.
Ich werde einige Beispiele geben.
scala> 1 == 1 res0: Boolean = true scala> 1 == 1.0 res1: Boolean = true scala> 1 == 1.2 res2: Boolean = false scala> 2 == BigInt(2) res3: Boolean = true scala> 2.0 == BigInt(2) res4: Boolean = true scala> 2 == BigInt(3) res5: Boolean = false
Bis jetzt ist nichts seltsam. Aber wenn wir die gleichen Dinge tun mit equals()
Methoden,
scala> 1 equals 1 res7: Boolean = true scala> 1 equals 1.0 res8: Boolean = false scala> 1 equals 1.2 res9: Boolean = false scala> 2 equals BigInt(2) res10: Boolean = false scala> 2.0 equals BigInt(2) res11: Boolean = false scala> 2 equals BigInt(3) res12: Boolean = false
Also, wenn die Typen unterschiedlich sind, gleich() immer false zurück, während == Tests, wenn sie den gleichen Wert darstellen, wenn sie auf die gleiche Art umgewandelt werden .
Im Fall der Unterklasse AnyRef
geben die Methoden ==
und equals()
dasselbe zurück.
scala> BigInt(2) == 2 res25: Boolean = true scala> BigInt(2) == 2.0 res26: Boolean = true scala> BigInt(3) == 2 res27: Boolean = false scala> BigInt(2) equals 2 res28: Boolean = true scala> BigInt(2) equals 2.0 res29: Boolean = true scala> BigInt(3) equals 2 res30: Boolean = false
Also, warum Methoden ==
und equals()
diffrent sind für AnyVal
?
Ich benutze Scala Version 2.10.2 (Java HotSpot (TM) 64-Bit Server VM, Java 1.7.0_25).
EDIT 1
ich sah, dass == nicht direkt überschrieben werden kann, wie es für alle als eine endgültige Methode in der Klasse definiert ist gemäß Programming in Scala, 2nd Edition.
BEARBEITEN 2
Obwohl es eine Antwort gibt, bleibt meine Frage. Ich werde diese Frage offen lassen.
Was in Java scala.Int
und scala.Long
entspricht, sind Javas primitive Typen int
und long
.
In Java, java.lang.Integer
und java.lang.Long
sind Klassen, so dass ihre Variablen Referenzen sind, die null
haben können. Das heißt, sie sind wie AnyRef
in Scala. Nicht AnyVal
.
Scala's AnyVal
- scala.Int
und scala.Long
können keine null
Werte haben, weder Java int
noch long
.
Auch java.lang.Integer
==
in Java ist für die Referenzgleichheit (das gleiche wie in Scala).
Was Sie mit Hilfe von java.lang.Integer
in Scala REPL erhalten, wird sich von dem unterscheiden, was Sie damit in reinem Java-Projekt mit .java-Quelldatei in dieser Hinsicht bekommen.
Was ich jedoch von der Verwendung Klassen von primitiven Typen in Java bekommen konnte, war: (dies ist 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))));
}
}
Ausgabe:
true false false true falseJa, sie zu scala AnyVal des
equals()
ähnlich verhalten. Aber warum passiert das?
Ist Scala AnyVal
‚s ==
-==
von Java primitivem Typ entsprechen
und hat Scala AnyVal des equals()
entspricht equals()
von Java-Klasse-Typen?
Was ist mit Gleichheitsprüfungen mit BigInt? Es gibt keinen entsprechenden primitiven Typ in Java.
Es bleibt die Frage ...
EDIT 3
ich einige Informationen von scaladoc finden konnten. (http://www.scala-lang.org/api/current/index.html#scala.Int)
Die Implizite Information aus dem Artikel von Beschattetes Implizite Wert Mitglieder,
ich ==
finden konnte, war für Char
, überlastet Short
, Float
, und ...,
und ==
werden implizite Konvertierungen nennen int2double
, int2float
oder int2long
.
Wobei equals()
nur für Any
definiert ist und die implizite Konvertierung int2Integer
aufgerufen wird.
Das heißt, Int.equals()
wird das gleiche sein wie java.lang.Integer.equals()
.
Eine Frage bleibt:
Warum ==
von AnyVal
überlastet ist, und equals()
von AnyVal
nicht überlastet ist?
Es tut mir leid, aber ich bin verwirrt, nach dem ganzen Beitrag. Können Sie bitte am Ende angeben, was genau die Frage ist? – Jatin
@Jatin Die Methode '==' und 'equals()' sind in 'AnyRef'-Werten in Scala identisch. Ich denke, sie sollten auch für 'AnyVal'-Werte gleich sein. In der Tat sind sie anders. Ich konnte jedoch nichts darüber finden, als ich Scala studierte. Also, warum '==' und 'equals()' sind nicht die gleichen für 'AnyVal'? Gibt es dazu eine Spezifikation? – Naetmul
@Naetmul, was ist mit dieser Ausgabe: 'println (Double.NaN == Double.NaN) println (Double.NaN gleich Double.NaN) ', ich war expectiong wahr und wahr, aber die Ausgabe ist falsch wahr, verstehe nicht es, jede Hilfe wird sehr geschätzt werden !!! – Aamir