Comprensione delle enumerazioni scala


122

Devo dire che non capisco le classi di enumerazione Scala. Posso copiare e incollare l'esempio dalla documentazione, ma non ho idea di cosa stia succedendo.

object WeekDay extends Enumeration {
  type WeekDay = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._
  • Cosa significa type WeekDay = Valuee perché devo scriverlo?
  • Perché lo è val Mon = Value? Che cosa vuol dire, anche?
  • Perché devo importare l' WeekDay oggetto? E,
  • quando scrivo val day = WeekDay.Mon, perché è un tipo WeekDay.Value, non un tipo WeekDay?

2
Ho scritto una piccola panoramica su scala Enumeration e alternative, potresti trovarla utile: pedrorijo.com/blog/scala-enums/
pedrorijo91

I tratti sigillati forniscono un'ottima alternativa - stackoverflow.com/questions/11203268/what-is-a-sealed-trait
Joey Baruch,

Risposte:


150

il Enumerationtratto ha un membro di tipo che Valuerappresenta i singoli elementi dell'enumerazione (in realtà è una classe interna, ma la differenza non ha importanza qui).

Quindi object WeekDayeredita quel tipo di membro. La linea type WeekDay = Valueè solo un alias di tipo . È utile, perché dopo averlo importato altrove con import WeekDay._, puoi usare quel tipo, ad esempio:

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

Invece, una versione minima sarebbe semplicemente:

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

e non è necessario importare il contenuto di object WeekDay, ma successivamente sarà necessario utilizzare il tipo WeekDay.Valuee per qualificare i singoli membri. Quindi l'esempio diventerebbe

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

La seconda domanda riguarda il significato di val Mon, ... = Value. Questo è davvero molto confuso se non si guarda all'implementazione di Enumeration. Questa non è l'assegnazione di un tipo! E 'invece un chiamando protetta metodo con lo stesso nome , Valueche restituisce un esempio concreto di tipo Value.

Accade così che è possibile scrivere val a, b, c = fooa Scala, e per ogni valore a, be cil metodo foosarà chiamato ancora e ancora. Enumerationusa questo trucco per incrementare un contatore interno in modo che ogni valore sia individuale.

Se apri i documenti dell'API Scala per Enumeratione fai clic su Visibility: All, vedrai apparire quel metodo.


2
Grazie, questo è molto confuso ma penso che sia giusto. Userò invece classi di casi sigillati, sembra più facile al 100%.
Karel Bílek

2
Personalmente preferisco anche le classi di casi sigillati. Un po 'più verboso, ma meno hokus-pokus con contatori interni mutabili e così via. Con Scala 2.10, ci sono alcune idee su come le enumerazioni (che a differenza di Java non sono un costrutto di linguaggio ma solo una soluzione di libreria) possono essere scritte meglio usando le macro.
0__

@ 0__ Posso chiederti perché e come usi la classe sealed per sostituire enum in Scala? C'è qualcosa di sbagliato nell'enumerazione di Scala?
x1a0

Cosa succede se i valori Enum stessi hanno membri? Come definiresti, ad esempio, gli orari di apertura di ogni giorno della settimana come: Lun (8,20), ..., Dom (0,0)?
simou

1
@simou allora dovresti davvero usare un tratto sigillato e delle sottoclassi effettive. Tuttavia, difficilmente chiamerei quello scenario una "enumerazione". Faresti meglio a scrivere Open(Mon, 8, 20)e i giorni rimarrebbero un'enumerazione piatta.
0__
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.