Understanding scala enumerations

I have to say I don't understand Scala enumeration classes. I can copy-paste the example from documentation, but I have no idea what is going on.

object WeekDay extends Enumeration {
type WeekDay = Value
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._
  • What means type WeekDay = Value and why do I have to write that?
  • Why is val Mon = Value? What does that even mean?
  • Why do I have to import the WeekDay object? And,
  • when I write val day = WeekDay.Mon, why is it type WeekDay.Value, not type WeekDay?
27267 次浏览

Enumeration trait 有一个类型成员 Value,它表示枚举的各个元素(它实际上是一个内部类,但这里的区别并不重要)。

Thus object WeekDay inherits that type member. The line type WeekDay = Value is just a type alias. It is useful, because after you import it elsewhere with import WeekDay._, you can use that type, e.g.:

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的具体实例。

It so happens that you can write val a, b, c = foo in Scala, and for each value a, b, and c the method foo will be called again and again. Enumeration uses this trick to increment an internal counter so that each value is individual.

If you open the Scala API docs for Enumeration and click on Visibility: All, you will see that method appearing.