Saya mencari di Google untuk menemukan perbedaan antara a case class
dan a class
. Semua orang menyebutkan bahwa ketika Anda ingin melakukan pencocokan pola di kelas, gunakan kelas kasus. Selain itu gunakan kelas dan juga menyebutkan beberapa fasilitas tambahan seperti equals dan kode hash menimpa. Tetapi apakah ini satu-satunya alasan mengapa seseorang harus menggunakan kelas kasus alih-alih kelas?
Saya kira harus ada alasan yang sangat penting untuk fitur ini di Scala. Apa penjelasannya atau apakah ada sumber untuk mempelajari lebih lanjut tentang kelas kasus Scala?
sumber
Secara teknis, tidak ada perbedaan antara kelas dan kelas kasus - bahkan jika kompilator tidak mengoptimalkan beberapa hal saat menggunakan kelas kasus. Namun, kelas kasus digunakan untuk menghilangkan pelat ketel untuk pola tertentu, yang menerapkan tipe data aljabar .
Contoh yang sangat sederhana dari jenis tersebut adalah pohon. Pohon biner, misalnya, dapat diimplementasikan seperti ini:
Itu memungkinkan kami untuk melakukan hal berikut:
Perhatikan bahwa pohon membangun dan mendekonstruksi (melalui pencocokan pola) dengan sintaks yang sama, yang juga persis bagaimana mereka dicetak (spasi minus).
Dan mereka juga dapat digunakan dengan peta atau set hash, karena mereka memiliki kode hash yang valid dan stabil.
sumber
(Anda sudah menyebutkan semua kecuali yang terakhir).
Itulah satu-satunya perbedaan dengan kelas reguler.
sumber
Tidak ada yang menyebutkan bahwa kelas kasus juga merupakan contoh
Product
dan dengan demikian mewarisi metode ini:di mana
productArity
mengembalikan jumlah parameter kelas,productElement(i)
mengembalikan parameter ke- i , dan memungkinkan iterasi melalui mereka.productIterator
sumber
Tidak ada yang menyebutkan bahwa kelas kasus memiliki
val
parameter konstruktor namun ini juga merupakan standar untuk kelas reguler (yang saya pikir merupakan ketidakkonsistenan dalam desain Scala). Dario tersirat seperti itu di mana ia mencatat mereka " tidak berubah ".Catatan Anda bisa mengganti default dengan menambahkan argumen setiap konstruktor dengan
var
untuk kelas kasus. Namun, membuat kelas kasus bisa berubah menyebabkan merekaequals
danhashCode
metode untuk waktu varian. [1]sepp2k telah menyebutkan bahwa kelas kasus secara otomatis menghasilkan
equals
danhashCode
metode.Juga tidak ada yang menyebutkan bahwa kelas kasus secara otomatis membuat pendamping
object
dengan nama yang sama dengan kelas, yang berisiapply
danunapply
metode. Theapply
Metode memungkinkan membangun contoh tanpa mengawali dengannew
. Theunapply
Metode extractor memungkinkan pencocokan pola yang lain disebutkan.Juga compiler mengoptimalkan kecepatan
match
-case
pencocokan pola untuk kelas kasus [2].[1] Kelas Kasus Keren
[2] Kelas Kasus dan Ekstraktor, hal 15 .
sumber
Konstruksi case case di Scala juga dapat dilihat sebagai kenyamanan untuk menghapus beberapa boilerplate.
Saat membangun kelas kasus, Scala memberi Anda yang berikut.
apply
metode yang dapat Anda gunakan sebagai metode pabrik. Anda mendapatkan keuntungan gula sintaksis karena tidak harus menggunakan kata kunci baru.Karena kelas tidak berubah Anda mendapatkan pengakses, yang hanya variabel (atau properti) dari kelas tetapi tidak ada mutator (jadi tidak ada kemampuan untuk mengubah variabel). Parameter konstruktor tersedia secara otomatis untuk Anda sebagai bidang hanya baca publik. Jauh lebih baik untuk digunakan daripada konstruk kacang Jawa.
hashCode
,,equals
dantoString
metode secara default danequals
metode membandingkan objek secara struktural. Suatucopy
metode dihasilkan untuk dapat mengkloning suatu objek (dengan beberapa bidang memiliki nilai baru yang disediakan untuk metode tersebut).Keuntungan terbesar seperti yang telah disebutkan sebelumnya adalah fakta bahwa Anda dapat mencocokkan pola pada kelas kasus. Alasannya adalah karena Anda mendapatkan
unapply
metode yang memungkinkan Anda mendekonstruksi kelas kasus untuk mengekstrak bidangnya.Pada dasarnya apa yang Anda dapatkan dari Scala ketika membuat kelas kasus (atau objek kasus jika kelas Anda tidak berdebat) adalah objek tunggal yang berfungsi sebagai pabrik dan sebagai ekstraktor .
sumber
copy
metode ini dapat memodifikasi bidang:val x = y.copy(foo="newValue")
Terlepas dari apa yang telah dikatakan orang, ada beberapa perbedaan mendasar antara
class
dancase class
1.
Case Class
tidak perlu eksplisitnew
, sedangkan kelas perlu dipanggil dengannew
2. Dengan parameter konstruktor default bersifat privat
class
, sementara publik dalamcase class
3.
case class
membandingkan diri mereka dengan nilaisumber
Menurut dokumentasi Scala :
Fitur lain dari kata kunci case adalah kompiler yang secara otomatis menghasilkan beberapa metode untuk kami, termasuk metode toString, equals, dan hashCode yang umum di Jawa.
sumber
Kelas:
Tetapi jika kita menggunakan kode yang sama tetapi menggunakan kelas kasus:
Kelas orang:
Pencocokan Pola:
objek: singleton:
sumber
Untuk memiliki pemahaman akhir tentang apa itu kelas kasus:
mari kita asumsikan definisi kelas kasus berikut:
dan kemudian lakukan hal berikut di terminal:
Scala 2.12.8 akan menampilkan:
Seperti yang dapat kita lihat Scala compiler menghasilkan kelas reguler
Foo
dan objek-pendampingFoo
.Mari kita melalui kelas yang dikompilasi dan mengomentari apa yang kita dapatkan:
Foo
kelas, tidak berubah:scala.Product
sifat:scala.Equals
sifat untuk instance kelas kasus yang sebanding dengan kesetaraan dengan==
:java.lang.Object.hashCode
untuk mematuhi kontrak equals-kode hash:java.lang.Object.toString
:new
kata kunci:Objek Foo: - metode
apply
untuk instantiasi tanpanew
kata kunci:unupply
untuk menggunakan kelas kasus Foo dalam pencocokan pola:scala.runtime.AbstractFunction2
untuk melakukan trik seperti itu:tupled
dari objek mengembalikan funtion untuk membuat Foo baru dengan menerapkan tuple 2 elemen.Jadi kelas kasus hanyalah gula sintaksis.
sumber
Tidak seperti kelas, kelas kasus hanya digunakan untuk menyimpan data.
Kelas kasus fleksibel untuk aplikasi data-sentris, yang berarti Anda bisa mendefinisikan bidang data dalam kelas kasus dan mendefinisikan logika bisnis di objek pendamping. Dengan cara ini, Anda memisahkan data dari logika bisnis.
Dengan metode salin, Anda dapat mewarisi salah satu atau semua properti yang diperlukan dari sumber dan dapat mengubahnya sesuka Anda.
sumber
Tidak ada yang menyebutkan bahwa objek kelas pendamping kasus memiliki
tupled
pembelaan, yang memiliki tipe:Satu-satunya use case yang dapat saya temukan adalah ketika Anda perlu membuat kelas case dari tuple, contoh:
Anda dapat melakukan hal yang sama, tanpa tupled, dengan membuat objek secara langsung, tetapi jika dataset Anda dinyatakan sebagai daftar tuple dengan arity 20 (tuple dengan 20 elemen), mungkin menggunakan tupled adalah pilihan Anda.
sumber
Kelas kasus adalah kelas yang dapat digunakan dengan
match/case
pernyataan.Anda lihat bahwa
case
diikuti oleh instance dari Fun kelas yang parameter ke-2-nya adalah Var. Ini adalah sintaks yang sangat bagus dan kuat, tetapi tidak dapat bekerja dengan instance dari kelas apa pun, oleh karena itu ada beberapa batasan untuk kelas kasus. Dan jika batasan ini dipatuhi, adalah mungkin untuk secara otomatis mendefinisikan kode hash dan yang sederajat.Ungkapan yang tidak jelas "mekanisme dekomposisi rekursif melalui pencocokan pola" berarti "bekerja dengan baik
case
". (Memang, instance diikuti olehmatch
dibandingkan dengan (cocok dengan) instance yang mengikuticase
, Scala harus membusuk mereka berdua, dan harus secara rekursif menguraikan apa yang mereka terbuat dari.)Untuk apa kelas kasus berguna? The Wikipedia artikel tentang Jenis aljabar data memberikan dua baik klasik contoh, daftar dan pohon. Dukungan untuk tipe data aljabar (termasuk mengetahui bagaimana membandingkannya) adalah suatu keharusan untuk bahasa fungsional modern.
Kelas kasus apa yang tidak berguna? Beberapa objek memiliki status, kode seperti
connection.setConnectTimeout(connectTimeout)
ini bukan untuk kelas kasus.Dan sekarang Anda dapat membaca A Tour of Scala: Class Case
sumber
Saya pikir secara keseluruhan semua jawaban telah memberikan penjelasan semantik tentang kelas dan kelas kasus. Ini bisa sangat relevan, tetapi setiap pemula di scala harus tahu apa yang terjadi ketika Anda membuat kelas kasus. Saya sudah menulis ini jawaban , yang menjelaskan kelas kasus secara singkat.
Setiap programmer harus tahu bahwa jika mereka menggunakan fungsi pre-built, maka mereka menulis kode yang relatif lebih sedikit, yang memungkinkan mereka dengan memberikan kekuatan untuk menulis kode yang paling optimal, tetapi kekuasaan datang dengan tanggung jawab besar. Jadi, gunakan fungsi prebuilt dengan sangat hati-hati.
Beberapa pengembang menghindari penulisan kelas kasus karena 20 metode tambahan, yang dapat Anda lihat dengan membongkar file kelas.
Silakan merujuk tautan ini jika Anda ingin memeriksa semua metode di dalam kelas kasus .
sumber
sumber
Beberapa fitur utama
case classes
tercantum di bawah ininew
kata kunci.Contoh kode scala pada scala fiddle, diambil dari scala docs.
https://scalafiddle.io/sf/34XEQyE/0
sumber