Понимание перечислений scala

Я должен сказать, что я не понимаю классы перечисления Scala. Я могу скопировать-вставить пример из документации, но я понятия не имею, что происходит.

object WeekDay extends Enumeration {
  type WeekDay = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._
  • Что означает type WeekDay = Value и зачем мне это писать?
  • Почему val Mon = Value? Что это значит?
  • Почему мне нужно импортировать WeekDay объект? И,
  • когда пишу val day = WeekDay.Mon, почему это тип WeekDay.Value, а не тип WeekDay?

Ответ 1

признак Enumeration имеет член типа Value, представляющий отдельные элементы перечисления (это фактически внутренний класс, но разница здесь не имеет значения).

Таким образом, object WeekDay наследует этот член типа. Строка type WeekDay = Value - это просто псевдоним типа. Это полезно, потому что после его импорта в другом месте с помощью import WeekDay._ вы можете использовать этот тип, например:

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

Вместо этого минимальная версия была бы следующей:

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

и вам не нужно импортировать содержимое object WeekDay, но тогда вам нужно будет использовать тип WeekDay.Value и квалифицировать отдельные члены. Таким образом, пример станет

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

Второй вопрос касается значения val Mon, ... = Value. Это действительно очень запутанно, если вы не смотрите на реализацию Enumeration. Это не назначение типа! Вместо этого он вызывает защищенный метод с тем же именем, Value, который возвращает конкретный экземпляр типа Value.

Так получилось, что вы можете написать val a, b, c = foo в Scala, а для каждого значения a, b и c метод foo будет вызываться снова и снова. Enumeration использует этот трюк, чтобы увеличить внутренний счетчик, чтобы каждое значение было индивидуальным.

Если вы откроете документы Scala API для Enumeration и нажмите Visibility: All, вы увидите, что этот метод появляется.