Nel scaladoc del scala.Any
, l'operatore ==
(o, il metodo ==
) è spiegato:Perché == operatore ed equals() comportarsi in modo diverso per i valori di AnyVal a 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
Per gli oggetti di sottoclassi di AnyRef
, Posso capirlo facilmente, e non ho visto nulla di strano.
Tuttavia, per i valori di AnyVal
, (intendo Int
, Double
, Long
, e così via,) la definizione di cui sopra è un po 'complicato (1 eq null
? Questo non compila se non ci convertiamo 1
a java.lang.Integer). Inoltre, ==
e equals()
si comportano diversamente.
Darò alcuni esempi.
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
Finora, nulla è strano. Ma se facciamo le stesse cose con equals()
metodi,
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
Quindi, se i tipi sono diversi, equals() restituisce sempre false, mentre == test se rappresentano lo stesso valore se vengono convertiti allo stesso tipo .
Nel caso della sottoclasse di AnyRef
, i metodi ==
e equals()
restituiscono lo stesso.
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
Quindi, perché i metodi ==
e equals()
sono differenti per AnyVal
?
Utilizzo la versione 2.10.2 di Scala (Java Server HotSpot (TM) a 64 bit, Java 1.7.0_25).
EDIT 1
ho visto che == non può essere sovrascritto direttamente, come è definito come un metodo final nella classe Qualunque secondo Programming in Scala, 2nd Edition.
EDIT 2
Anche se c'è una risposta, la mia domanda rimane. Lascerò questa domanda aperta.
Ciò che corrisponde a scala.Int
e scala.Long
in Java sono i tipi primitivi di Java int
e long
.
In Java, java.lang.Integer
e java.lang.Long
sono classi, quindi le loro variabili sono riferimenti, che possono avere null
. Ciò significa che sono come AnyRef
in Scala. Non AnyVal
.
Scala AnyVal
- scala.Int
e scala.Long
non possono avere valori , né Javae long
.
Inoltre, lo ==
di in Java è per l'uguaglianza di riferimento (uguale a eq
in Scala).
Quello che si ottiene usando java.lang.Integer
in Scala REPL sarà molto diverso da quello che si ottiene con esso in puro Progetto Java con file di origine .java a questo riguardo.
Tuttavia, ciò che ho potuto ottenere di utilizzare classi di tipi primitivi in Java è stato: (Questo è 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))));
}
}
uscita:
true false false true falseSì, si comportano simile alla Scala AnyVal di
equals()
. Ma, allora, perché succede?
Does AnyVal
s' ==
di Scala corrispondono a ==
di tipo primitivo di Java
e fa della Scala AnyVal equals()
corrispondono a equals()
delle tipologie di classi di Java?
E i test di uguaglianza con BigInt? Non esiste un tipo primitivo corrispondente in Java.
La questione rimane ...
EDIT 3
sono riuscito a trovare alcune informazioni da scaladoc. (http://www.scala-lang.org/api/current/index.html#scala.Int)
Il informazioni implicite dalla voce di ombreggiato implicite di valore Utenti,
ho potuto trovare ==
era sovraccarica per Char
, Short
, Float
, e ...,
e ==
chiamerà conversioni implicite int2double
, int2float
o int2long
.
Mentre equals()
è definito solo per Any
e chiama la conversione implicita int2Integer
.
Cioè, Int.equals()
sarà lo stesso di java.lang.Integer.equals()
.
Una domanda rimane:
Perché ==
di AnyVal
è sovraccarico, e equals()
di AnyVal
non sovraccaricare?
Mi dispiace, ma sono confuso dopo l'intero post. Puoi specificare alla fine di quale è la domanda esatta? – Jatin
@Jatin Il metodo '==' e 'equals()' sono gli stessi nei valori di 'AnyRef' in Scala. Penso che dovrebbero essere uguali anche per i valori di 'AnyVal'. In realtà, sono diversi. Tuttavia, non ho trovato nulla a riguardo mentre stavo studiando Scala. Quindi, perché '==' e 'equals()' non sono gli stessi per 'AnyVal'? C'è qualche specifica su questo? – Naetmul
@Naetmul, che dire di questo output: 'println (Double.NaN == Double.NaN) println (Double.NaN uguale a Double.NaN) ', ero expectiong vero e vero ma l'output è falso vero, non capisco ogni aiuto sarà molto apprezzato !!! – Aamir