2010-03-19 17 views
24

Per quanto ho capito, Scala == definisce l'uguaglianza naturale di due oggetti.Perché `Array (0,1,2) == Array (0,1,2)` non restituisce il risultato previsto?

Mi aspettavo che Array(0,1,2) == Array(0,1,2) confronta l'uguaglianza naturale. Ad esempio, controlla se tutti gli elementi dell'array restituiscono true se confrontati con gli elementi corrispondenti dell'altro array.

La gente mi ha detto che lo Array di Scala è solo un Java [] che confronta solo l'identità. Non sarebbe più utile sovrascrivere il metodo per confrontare l'uguaglianza naturale?

+0

Non ho familiarità con Scala. Tuttavia, sei sicuro == non sta confrontando se gli array sono alias (riferimenti allo stesso oggetto in memoria)? Presumo che questa sia una possibilità, dal momento che hai menzionato che è relativo a un array Java. – Cam

+1

È una situazione sfortunata, come le altre risposte descrivono, ma quando sai che hai a che fare con Array, puoi usare sameElements e ottenere la risposta che desideri evitando tutto il wrapping, il pugilato e le circonlocuzioni. –

risposta

19

Scala 2.7 cercato di aggiungere funzionalità a Java [] array, e corse in casi d'angolo che erano problematici. Scala 2.8 ha dichiarato che Array[T] è T[], ma fornisce wrapper e equivalenti.

Prova quanto segue in 2.8 (Edit/nota: come di RC3, GenericArray è ArraySeq --thanks per retronym per la precisazione):

import scala.collection.mutable.{GenericArray=>GArray, WrappedArray=>WArray} 
scala> GArray(0,1,2) == GArray(0,1,2) 
res0: Boolean = true 

scala> (Array(0,1,2):WArray[Int]) == (Array(0,1,2):WArray[Int]) 
res1: Boolean = true 

GenericArray agisce proprio come Array, se non con tutta la Scala raccolte aggiunte aggiunte. WrappedArray wraps Java [] array; sopra, ho lanciato una matrice semplice (più facile che chiamare la funzione di conversione implicita) e poi ho confrontato gli array avvolti. Questi wrapper, sebbene supportati da un array [], offrono anche tutti i gadget per la raccolta.

+0

Ci sono prestazioni/memoria/dattilografia/... benefici dall'utilizzo di queste classi invece di e. g. una lista allora? Potrei immaginare che GenericArray/WrappedArray aggiunga un po 'di overhead ... – soc

+1

No, in realtà, aggiungono poco overhead: 'WrappedArray' è una classe extra avvolta attorno ad un semplice array Java. 'List' richiede una classe extra intorno a _every single element_. Si utilizzano gli elenchi a causa della facilità d'uso e della corrispondenza dei modelli e dell'immutabilità, non per l'efficienza. 'GenericArray' ha una posizione leggermente dispari, tuttavia, come una matrice di dimensioni fisse: la dimensione è immutabile ma il contenuto è mutabile.Perché, ci si potrebbe chiedere, non usare semplicemente un 'ArrayBuffer'? –

+1

È possibile utilizzare un elenco immutabile a causa delle prestazioni. Le collezioni immutabili possono salvarti dal dover fare copie difensive. A seconda dell'applicazione, questo può superare il sovraccarico. – ziggystar

5

Ma stringa di Scala è anche solo una stringa Java ma Scala prevale uguale a confrontare uguaglianza naturale.

Scala non sovrasta nulla; java.lang.String ha un'implementazione dipendente dal valore di equals() (come molte altre classi Java, ma a differenza degli array).

+0

Ciao Michael, grazie! Ho risolto la mia domanda di conseguenza. Fondamentalmente mi chiedo perché l'uguaglianza non sia sovrascritta per restituire l'uguaglianza naturale come le classi Collection (so che l'array non appartiene alle classi Collection!). – soc

+3

Scala interprets '==' come 'equals'. È tutto. 'String' ha un' equals' che fa qualcosa di diverso dall'identità di riferimento. '[]' non lo fa. –

8

Scala non ignorare l'uguaglianza di Array perché non è possibile. Si possono sovrascrivere solo i metodi quando si esegue la sottoclasse. Poiché Array non viene sottoposto a sottoclassi (il che non è possibile), Scala non può sovrascrivere i suoi metodi.

Problemi correlati