Noções básicas sobre enumerações de scala

122

Devo dizer que não entendo as classes de enumeração Scala. Posso copiar e colar o exemplo da documentação, mas não tenho ideia do que está acontecendo.

object WeekDay extends Enumeration {
  type WeekDay = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._
  • O que significa type WeekDay = Valuee por que eu tenho que escrever isso?
  • Por que val Mon = Value? Afinal, o que isso quer dizer?
  • Por que tenho que importar o WeekDay objeto? E,
  • quando escrevo val day = WeekDay.Mon, por que é do tipo WeekDay.Value, não do tipo WeekDay?
Karel Bílek
fonte
2
Eu escrevi uma pequena visão geral sobre scala enumeração e alternativas, você pode achar que é útil: pedrorijo.com/blog/scala-enums/
pedrorijo91
Os traços selados oferecem uma excelente alternativa - stackoverflow.com/questions/11203268/what-is-a-sealed-trait
Joey Baruch

Respostas:

150

a Enumerationcaracterística possui um membro de tipo que Valuerepresenta os elementos individuais da enumeração (na verdade, é uma classe interna, mas a diferença não importa aqui).

Assim, object WeekDayherda esse membro do tipo. A linha type WeekDay = Valueé apenas um alias de tipo . É útil, porque depois de importá-lo para outro lugar import WeekDay._, você pode usar esse tipo, por exemplo:

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

Em vez disso, uma versão mínima seria apenas:

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

e você não precisa importar o conteúdo de object WeekDay, mas precisará usar o tipo WeekDay.Valuee qualificar membros individuais. Então o exemplo se tornaria

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

A segunda pergunta é sobre o significado de val Mon, ... = Value. Isso é realmente muito confuso se você não analisar a implementação do Enumeration. Esta não é a atribuição de um tipo! É, em vez de chamar um protegido método de mesmo nome , Valueque retorna uma instância de concreto do tipo Value.

Acontece que você pode escrever val a, b, c = fooem Scala, e para cada valor a, be, co método fooserá chamado novamente e novamente. Enumerationusa esse truque para incrementar um contador interno para que cada valor seja individual.

Se você abrir os documentos da API Scala Enumeratione clicar em Visibility: All, verá esse método aparecendo.

0__
fonte
2
Obrigado, isso é muito confuso, mas acho que está certo. Em vez disso, usarei classes de casos selados, parece 100% mais fácil.
Karel Bílek
2
Pessoalmente, também prefiro aulas de casos selados. Um pouco mais detalhado, mas menos hokus-pokus com contadores internos mutáveis ​​e assim por diante. Com o Scala 2.10, existem algumas idéias de como as enumerações (que, diferentemente do Java, não são uma construção de linguagem, mas apenas uma solução de biblioteca) podem ser escritas melhor usando macros.
0__
@ 0__ Posso perguntar por que e como você usa a classe selada para substituir o enum no Scala? Há algo de errado com a enumeração de Scala?
X1a0
E se os próprios valores da Enum tiverem membros? Como você definiria, por exemplo, o horário de funcionamento de cada dia da semana, como: seg (8,20), ..., sol (0,0)?
Simou
1
@simou, então você deve realmente usar uma característica selada e subclasses reais. Eu dificilmente chamaria esse cenário de "enumeração". É melhor escrever Open(Mon, 8, 20)e os dias permanecerão uma enumeração simples.
0__