By Andres Jaimes

- 2 minutes read - 275 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:

sealed trait OperatingSystem extends Product with Serializable

object OperatingSystem {
  case object FreeBsd extends OperatingSystem
  case object Debian extends OperatingSystem
  case object Alpine extends OperatingSystem
  case object Arch extends OperatingSystem
  case object Osx extends OperatingSystem

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

scala> OperatingSystem.FreeBsd
val res1: OperatingSystem.Value = FreeBsd

scala> OperatingSystem.FreeBsd.toString
val 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:

operatingSystem match {
  case Debian => ???
  case Alpine => ???
  case Arch => ???
  case Osx => ???

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:

scala> object OperatingSystem extends Enumeration {
    val FreeBsd, Debian, Alpine, Arch, Osx = Value
val res1: object OperatingSystem

scala> OperatingSystem.FreeBsd
val res2: OperatingSystem.Value = FreeBsd

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

scala> OperatingSystem.FreeBsd.toString
val res3: String = FreeBsd

scala> OperatingSystem.withName("Debian")
val res4: OperatingSystem.Value = Debian

scala> OperatingSystem.withName("Windows")
java.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.

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