Java Перечисление
Для перечисления класса Counter
будет лучше, чем именем Counters
- каждое значение перечисления представляет исключительный счетчик.
Когда Javac компилирует enum
класса, это:
- компилируется в обычный класс Java (например,
Counter
), содержащие все конструкторы, методы, другие членов перечисления (если таковой имеется)
каждая enum
значение (GOOD_THING
, BAD_THING
) выполнен в public static
поле (1) - с классом, равным классу в (1) (Counter
):
// Java Code:
class Counter {
public static Counter GOOD_THING;
public static Counter BAD_THING;
// constructors, methods, fields as defined in the enum ...
}
инициализации логики в классе автоматически создает каждый enum
значение как единственный объект
Scala Опции
А. Эталонный Java Enum От Scala
Импорт счетчика, см для GOOD_THING и BAD_THING, как в java, и (если хотите) дополнительно вызовите методы класса Enum:
// Scala Code:
import JavaSubClass.Counter;
def someDistributedTask = {
// some work here
if (terribleThing) {
loggingMethod(Counter.BAD_THING)
} else {
loggingMethod(Counter.GOOD_THING)
// more work here
}
}
// Other things you can do:
val GoodThing = Counter.valueOf("GOOD_THING")
Counter.values() foreach { // do something }
counter match {
case Counter.GOOD_THING => "Hoorah"
case Counter.BAD_THING => "Pfft"
case _ => throw new RuntimeException("someone added a new value?")
}
Преимущества: Можно делать все, что перечислены в java, а также поддерживает сопоставление шаблонов. Недостатки: поскольку базовый признак не является sealed
, любой код, выполняющий сопоставление с образцом, не проверяется на печать, чтобы гарантировать, что исчерпывающие случаи закрыты.
B. Использование Scala Перечень
Преобразование Java enum
эквивалентное Scala Enumeration
:
// Scala Code:
object Counter extends Enumeration {
type Counter = Value
val GoodThing = Value("GoodThing")
val BadThing = Value("BadThing")
}
Использование:
// Scala Code:
import someScalaPackage.Counter;
def someDistributedTask = {
// some work here
if (terribleThing) {
loggingMethod(Counter.BadThing)
} else {
loggingMethod(Counter.GoodThing)
// more work here
}
}
// Other things you can do:
val GoodThing = Counter.withName("GoodThing")
val label = Counter.BadThing.toString
Counter.values foreach { // do something }
myCounter match {
case Counter.GOOD_THING => "Bully!"
case Counter.BAD_THING => "Meh"
case _ => throw new RuntimeException("someone added a new value?")
}
Преимущества: Enumeration
методы Scala является так богата, как Java Enum
, плюс поддержка соответствия шаблону. Disadvanges: Невозможно сделать все, что java enum
s do - java enum определены как класс с допустимыми конструкциями, методами и другими членами (т. Е. Полное OO-моделирование для базового типа перечисления). Поскольку базовый признак не равен sealed
, любой код, выполняющий сопоставление с образцом, не проверяется на типизацию, чтобы обеспечить исчерпывающие случаи.
C. Использование Scala Case Классы:
может преобразовать enum
s непосредственно в Case Objects (то есть одноплодная объекты, в отличие от случая класса, который не является синглтоном):
sealed trait Counter
object Counter {
case object GoodThing extends Counter;
case object BadThing extends Counter;
}
Используйте его :
// Scala Code:
import someScalaPackage.Counter;
def someDistributedTask = {
// some work here
if (terribleThing) {
loggingMethod(Counter.BadThing)
} else {
loggingMethod(Counter.GoodThing)
// more work here
}
}
// Other things you can do:
// NO!! val GoodThing = Counter.withName("GoodThing")
val label = Counter.BadThing.toString
// NO!! Counter.values foreach { // do something }
myCounter match {
case Counter.GOOD_THING => "Bully!"
case Counter.BAD_THING => "Meh"
case _ => throw new RuntimeException("someone added a new value?")
}
- преимущество над исчислением : каждое значение может иметь разные предки или разные признаки микса (до тех пор, пока каждое значение соответствует типу Counter). Могут делать arbirtrarily сложное OO-моделирование для счетчика признаков и для каждого значения. Затем можно выполнить произвольно сложное сопоставление шаблонов, используя все различные параметры объекта case для каждого другого значения. Имея базовый признак
sealed
, любой код, выполняющий сопоставление с образцом, проверяется на соответствие, чтобы гарантировать, что исчерпывающие случаи закрыты. (Не подходит для ваших требований).
- Недостаток над перечислением: не получайте методы перечисления «бесплатно» (т. Е. Значения, withName, application). Может быть «исправлена» путем добавления пользовательских реализаций к базовому классу Counter (немного для справки, поскольку это ручное кодирование ...).
Даже если вы переходите на scala, вы все равно можете написать java перечисления и использовать их из своего scala-кода. Scala не упрощает создание перечислений IMHO; запечатанная черта и набор объектов намного проще и, я считаю, предпочтительнее. – vptheron
https://gist.github.com/viktorklang/1057513 – oluies
После обширного исследования всех вариантов «перечислений» в Scala я опубликовал гораздо более полный обзор этого домена в другом потоке StackOverflow. Он включает решение шаблона «запечатанный образец + случайный объект», где я решил проблему упорядочения инициализации класса/объекта JVM: http://stackoverflow.com/a/25923651/501113 – chaotic3quilibrium