Enumerations
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