ChatGPT解决这个技术问题 Extra ChatGPT

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?

I've written a small overview about scala Enumeration and alternatives, you may find it useful: pedrorijo.com/blog/scala-enums/
Sealed traits provide an excellent alternative - stackoverflow.com/questions/11203268/what-is-a-sealed-trait

0
0__

the Enumeration trait has a type member Value representing the individual elements of the enumeration (it's actually an inner class, but the difference doesn't matter here).

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)

Instead, a minimal version would just be:

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

and you do not have to import the contents of object WeekDay, but then you would need to use type WeekDay.Value and to qualify individual members. So the example would become

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

The second question is about the meaning of val Mon, ... = Value. This is indeed very confusing if you don't look into the implementation of Enumeration. This is not the assignment of a type! It is instead calling a protected method of the same name, Value, which returns a concrete instance of type 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.


Thanks, this is very confusing but I think it's right. I will use sealed case classes instead, it seems 100% easier.
I personally prefer sealed case classes, too. A bit more verbose, but less hokus-pokus with mutable internal counters and so forth. With Scala 2.10, there are some ideas how enumerations (which unlike Java are not a language construct but just a library solution) can be written better using macros.
@0__ May I ask why and how do you use sealed class to replace enum in Scala? Is there anything wrong with Scala's Enumeration?
What if Enum values themselves have members? How would you for instance define opening hours for each day of the week like: Mon(8,20), ..., Sun(0,0) ?
@simou then you should indeed use a sealed trait and actual sub classes. I would hardly call that scenario an "enumeration", though. You might better write Open(Mon, 8, 20) and the days would remain a flat enumeration.

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now