Apa perbedaan antara ==
dan .equals()
dalam Scala, dan kapan menggunakannya?
Apakah implementasinya sama dengan di Jawa?
EDIT: Pertanyaan terkait berbicara tentang kasus spesifik AnyVal
. Kasus yang lebih umum adalah Any
.
Apa perbedaan antara ==
dan .equals()
dalam Scala, dan kapan menggunakannya?
Apakah implementasinya sama dengan di Jawa?
EDIT: Pertanyaan terkait berbicara tentang kasus spesifik AnyVal
. Kasus yang lebih umum adalah Any
.
Jawaban:
Anda biasanya menggunakan
==
, itu rute keequals
, kecuali itu memperlakukannull
dengan benar. Referensi kesetaraan (jarang digunakan) adalaheq
.sumber
3 == BigInt(3)
danBigInt(3) == 3
itu benar. Tapi,3.equals(BigInt(3))
itu salah, padahalBigInt(3).equals(3)
itu benar. Karena itu, lebih suka menggunakan==
. Hindari penggunaanequals()
dalam skala. Saya pikir==
melakukan konversi tersirat dengan baik, tetapiequals()
tidak.new java.lang.Integer(1) == new java.lang.Double(1.0)
benar sementaranew java.lang.Integer(1) equals new java.lang.Double(1.0)
itu salah?==
adalah metode terakhir, dan panggilan.equals
, yang tidak final.Ini sangat berbeda dari Jawa, di mana
==
operator daripada metode dan secara ketat membandingkan kesetaraan referensi untuk objek.sumber
TL; DR
equals
metode untuk membandingkan konten setiap instance. Ini adalahequals
metode yang sama yang digunakan di Jawa==
operator untuk membandingkan, tanpa khawatir tentangnull
referensieq
metode untuk memeriksa apakah kedua argumen tersebut PERSIS referensi yang sama. Dianjurkan untuk tidak menggunakan kecuali Anda mengerti bagaimana ini bekerja dan seringequals
akan bekerja untuk apa yang Anda butuhkan. Dan pastikan untuk hanya menggunakan ini denganAnyRef
argumen, bukan hanyaAny
CATATAN: Pada kasus
equals
, seperti halnya di Jawa, ini mungkin tidak mengembalikan hasil yang sama jika Anda mengganti argumen mis.1.equals(BigInt(1))
Akan mengembalikanfalse
tempat invers akan kembalitrue
. Ini karena setiap implementasi hanya memeriksa jenis tertentu. Bilangan primitif tidak memeriksa apakah argumen kedua adalah tipeNumber
atau bukanBigInt
tetapi hanya tipe primitif lainnyaDetail
The
AnyRef.equals(Any)
Metode adalah salah satu ditimpa oleh subclass. Metode dari Spesifikasi Java yang telah datang ke Scala juga. Jika digunakan pada instance unboxed, itu kotak untuk memanggil ini (meskipun tersembunyi di Scala; lebih jelas di Jawa denganint
->Integer
). Implementasi default hanya membandingkan referensi (seperti di Jawa)The
Any.==(Any)
Metode membandingkan dua benda dan memungkinkan argumen baik untuk menjadi nol (seolah-olah memanggil metode statis dengan dua contoh). Ini membandingkan jika keduanyanull
, maka itu memanggilequals(Any)
metode pada contoh kotak.The
AnyRef.eq(AnyRef)
Metode membandingkan hanya referensi, yang mana contoh terletak di memori. Tidak ada tinju tersirat untuk metode ini.Contohnya
1 equals 2
akan kembalifalse
, karena dialihkan keInteger.equals(...)
1 == 2
akan kembalifalse
, karena dialihkan keInteger.equals(...)
1 eq 2
tidak akan dikompilasi, karena kedua argumen harus bertipeAnyRef
new ArrayList() equals new ArrayList()
akan kembalitrue
, karena memeriksa kontennew ArrayList() == new ArrayList()
akan kembalitrue
, karena dialihkan keequals(...)
new ArrayList() eq new ArrayList()
akan kembalifalse
, karena kedua argumen adalah contoh yang berbedafoo equals foo
akan kembalitrue
, kecualifoo
adalahnull
, maka akan melemparNullPointerException
foo == foo
akan kembalitrue
, bahkan jikafoo
adanull
foo eq foo
akan kembalitrue
, karena kedua argumen terhubung ke referensi yang samasumber
Ada perbedaan yang menarik antara
==
danequals
untukFloat
danDouble
jenis: Mereka memperlakukan secaraNaN
berbeda:Sunting: Seperti yang ditunjukkan dalam komentar - "ini juga terjadi di Jawa" - tergantung pada apa tepatnya ini :
Ini akan dicetak
Jadi,
unboxedNan
hasilnyafalse
ketika dibandingkan untuk kesetaraan karena ini adalah bagaimana angka-angka floating point IEEE mendefinisikannya dan ini harus benar-benar terjadi di setiap bahasa pemrograman (meskipun entah bagaimana mengacaukan gagasan identitas).Kotak NaN menghasilkan true untuk perbandingan menggunakan
==
di Jawa karena kami membandingkan referensi objek.Saya tidak punya penjelasan untuk
equals
kasus ini, IMHO itu benar-benar harus berperilaku sama seperti==
pada nilai ganda tanpa kotak, tetapi tidak.Diterjemahkan ke Scala masalah ini sedikit lebih rumit karena Scala telah menyatukan jenis objek primitif dan menjadi
Any
dan menerjemahkan ke dalam primitif ganda dan kotak ganda yang diperlukan. Dengan demikian scala==
tampaknya bermuara pada perbandinganNaN
nilai-nilai primitif tetapiequals
menggunakan yang didefinisikan pada nilai ganda kotak (ada banyak sihir konversi implisit yang terjadi dan ada hal-hal yang di gandakan menjadi ganda olehRichDouble
).Jika Anda benar-benar perlu mencari tahu apakah sesuatu benar-benar
NaN
digunakanisNaN
:sumber
Dalam Scala == pertama periksa nilai Null dan kemudian memanggil metode sama dengan objek pertama
sumber