Memahami enumerasi skala

122

Saya harus mengatakan saya tidak mengerti kelas pencacahan Scala. Saya dapat menyalin-tempel contoh dari dokumentasi, tetapi saya tidak tahu apa yang sedang terjadi.

object WeekDay extends Enumeration {
  type WeekDay = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._
  • Apa artinya type WeekDay = Valuedan mengapa saya harus menulis itu?
  • Mengapa val Mon = Value? Apa artinya itu?
  • Mengapa saya harus mengimpor WeekDay objek? Dan,
  • ketika saya menulis val day = WeekDay.Mon, mengapa itu mengetik WeekDay.Value, bukan mengetik WeekDay?
Karel Bílek
sumber
2
Saya telah menulis gambaran umum kecil tentang pencacahan scala dan alternatif, Anda mungkin merasa berguna: pedrorijo.com/blog/scala-enums/
pedrorijo91
Sifat tersegel memberikan alternatif yang sangat baik - stackoverflow.com/questions/11203268/what-is-a-sealed-trait
Joey Baruch

Jawaban:

150

yang Enumerationsifat memiliki anggota jenis Valueyang mewakili unsur-unsur individual dari pencacahan (itu sebenarnya kelas batin, tetapi perbedaannya tidak penting di sini).

Jadi object WeekDaymewarisi anggota tipe itu. Garis type WeekDay = Valuetersebut hanyalah sebuah alias tipe . Ini berguna, karena setelah Anda mengimpornya ke tempat lain dengan import WeekDay._, Anda dapat menggunakan jenis itu, misalnya:

def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun)

Sebaliknya, versi minimalnya adalah:

object WeekDay extends Enumeration {
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}

dan Anda tidak perlu mengimpor konten object WeekDay, tetapi Anda harus menggunakan type WeekDay.Valuedan untuk memenuhi syarat anggota individu. Jadi contohnya akan menjadi

def isWorkingDay(d: WeekDay.Value) = ! (d == WeekDay.Sat || d == WeekDay.Sun)

Pertanyaan kedua adalah tentang arti dari val Mon, ... = Value. Ini memang sangat membingungkan jika Anda tidak melihat ke dalam implementasinya Enumeration. Ini bukan penugasan tipe! Hal ini bukan memanggil dilindungi metode dengan nama yang sama , Valueyang mengembalikan contoh konkret dari jenis Value.

Hal ini terjadi bahwa Anda dapat menulis val a, b, c = foodi Scala, dan untuk setiap nilai a, bdan cmetode fooakan dipanggil lagi dan lagi. Enumerationmenggunakan trik ini untuk menaikkan penghitung internal sehingga setiap nilai bersifat individual.

Jika Anda membuka dokumen Scala API Enumerationdan mengkliknya Visibility: All, Anda akan melihat metode itu muncul.

0__
sumber
2
Terima kasih, ini sangat membingungkan tetapi saya pikir itu benar. Saya akan menggunakan kelas kasus tertutup sebagai gantinya, tampaknya 100% lebih mudah.
Karel Bílek
2
Saya pribadi lebih suka kelas kasus tertutup juga. Sedikit lebih bertele-tele, tetapi kurang hokus-pokus dengan penghitung internal yang bisa berubah dan sebagainya. Dengan Scala 2.10, ada beberapa ide bagaimana enumerasi (yang tidak seperti Java bukanlah konstruksi bahasa tetapi hanya solusi perpustakaan) dapat ditulis lebih baik menggunakan makro.
0__
@ 0__ Bolehkah saya bertanya mengapa dan bagaimana Anda menggunakan kelas tersegel untuk mengganti enum di Scala? Apakah ada yang salah dengan Scala's Enumeration?
x1a0
Bagaimana jika nilai Enum sendiri memiliki anggota? Bagaimana Anda misalnya menentukan jam buka untuk setiap hari dalam seminggu seperti: Sen (8,20), ..., Sun (0,0)?
simou
1
@ Simou maka Anda memang harus menggunakan sifat tersegel dan sub kelas yang sebenarnya. Saya tidak akan menyebut skenario itu sebagai "pencacahan". Anda mungkin lebih baik menulis Open(Mon, 8, 20)dan hari-hari akan tetap menjadi pencacahan datar.
0__