avatar

Andres Jaimes

Enumerations

By Andres Jaimes

- 2 minutes read - 290 words

Using case object

Unlike other languages, Scala does not have a keyword for enumerations. One way to implement them is by using case objects. For example:

1sealed trait OperatingSystem extends Product with Serializable
2
3object OperatingSystem {
4  case object FreeBsd extends OperatingSystem
5  case object Debian extends OperatingSystem
6  case object Alpine extends OperatingSystem
7  case object Arch extends OperatingSystem
8  case object Osx extends OperatingSystem
9}

To use it, just define a value of type OperatingSystem. You can even get a string representation from these values:

1scala> OperatingSystem.FreeBsd
2val res1: OperatingSystem.Value = FreeBsd
3
4scala> OperatingSystem.FreeBsd.toString
5val res2: String = FreeBsd

A big plus of using this approach vs using plain strings, is that the compiler can warn you if you have match conditions that are missing values. For example:

1operatingSystem match {
2  case Debian => ???
3  case Alpine => ???
4  case Arch => ???
5  case Osx => ???
6}

displays the following compilation warning:

match may not be exhaustive.
It would fail on the following input: FreeBsd
  operatingSystem match {

Extending Enumeration

A second option to implement them is to extend from Enumeration:

1scala> object OperatingSystem extends Enumeration {
2    val FreeBsd, Debian, Alpine, Arch, Osx = Value
3}
4val res1: object OperatingSystem
5
6scala> OperatingSystem.FreeBsd
7val res2: OperatingSystem.Value = FreeBsd

Extending Enumeration is simpler if you have to convert values from strings.

1scala> OperatingSystem.FreeBsd.toString
2val res3: String = FreeBsd
3
4scala> OperatingSystem.withName("Debian")
5val res4: OperatingSystem.Value = Debian
6
7scala> OperatingSystem.withName("Windows")
8java.util.NoSuchElementException: No value found for 'Windows'

find can be used to avoid receiving an exception when there’s no certainty about the values you are looking for.

1scala> OperatingSystem.values.find(_.toString == "Windows")
2val res5: Option[OperatingSystem.Value] = None

References