Skip to content
Snippets Groups Projects
progfun1-3-5.md 2.76 KiB
Newer Older
% Enums
Martin Odersky's avatar
Martin Odersky committed
%
%

Enums: Motivation
=================
Martin Odersky's avatar
Martin Odersky committed

Julien Richard-Foy's avatar
Julien Richard-Foy committed
We have seen that classes can *aggregate several values* into a single abstraction.
For instance, the `Rational` class aggregates a numerator and a denominator.
Martin Odersky's avatar
Martin Odersky committed

Conversely, how could we define an abstraction *accepting alternative values*?
Martin Odersky's avatar
Martin Odersky committed

\example
Martin Odersky's avatar
Martin Odersky committed

Define a `Color` type with values `Red`, `Green`, `Blue`, and `Magenta`.
Martin Odersky's avatar
Martin Odersky committed

Color Objects
Martin Odersky's avatar
Martin Odersky committed
=============

~~~
  trait Color
  object Red extends Color
  object Green extends Color
  object Blue extends Color
  object Magenta extends Color
~~~
Martin Odersky's avatar
Martin Odersky committed

->
This is getting tedious!
Martin Odersky's avatar
Martin Odersky committed

Is there a simpler way?
Martin Odersky's avatar
Martin Odersky committed

Enums
=====
Martin Odersky's avatar
Martin Odersky committed

As a simpler and shorter alternative, we
can define a type with its values in an \red{enum}:
Martin Odersky's avatar
Martin Odersky committed

  enum Color with
    case Red, Green, Blue, Magenta
~~~
Martin Odersky's avatar
Martin Odersky committed

This definition introduces:
Martin Odersky's avatar
Martin Odersky committed

- A new \red{type}, named `Color`.
- Four possible \red{values} for this type, `Color.Red`, `Color.Green`, `Color.Blue`, and
  `Color.Magenta`.
Martin Odersky's avatar
Martin Odersky committed

Enumerate the Values of an Enumeration
======================================
Martin Odersky's avatar
Martin Odersky committed

It is possible to enumerate all the values of an enum by calling the
`values` operation on the enum companion object:
Martin Odersky's avatar
Martin Odersky committed

\begin{tabular}{ll}
 \verb@Color.values@              \wsf Array(Red, Green, Blue, Magenta) \\
 \verb@val c = Color.Green@       \wsf c: Color = Green \\
Julien Richard-Foy's avatar
Julien Richard-Foy committed
 \verb@c == Color.values(1)@      \wsf true
\end{tabular}
Martin Odersky's avatar
Martin Odersky committed

Discriminate the Values of an Enumeration
=========================================
Martin Odersky's avatar
Martin Odersky committed

You can discriminate between the values of an enum by using a \red{match}
expression:
Martin Odersky's avatar
Martin Odersky committed

~~~
  import Color._
  def isPrimary(color: Color): Boolean =
    color match
      case Red | Green | Blue => true
      case Magenta => false
~~~
Martin Odersky's avatar
Martin Odersky committed

Match Syntax
============
Martin Odersky's avatar
Martin Odersky committed

- `match` is followed by a sequence of \red{cases}, `case value => expr`.
- Each case associates an \red{expression} `expr` with a
  \red{constant} `value`.
- Default cases are written with an underscore, e.g.
Martin Odersky's avatar
Martin Odersky committed

Julien Richard-Foy's avatar
Julien Richard-Foy committed
  def isPrimary(color: Color): Boolean = color match
    case Magenta => false
    case _ => true
~~~
Martin Odersky's avatar
Martin Odersky committed

We will see later that pattern matching can do more
than discriminating enums.
Martin Odersky's avatar
Martin Odersky committed

Enumerations Can Take Parameters
================================
Martin Odersky's avatar
Martin Odersky committed

  enum Vehicle(val numberOfWheels: Int) with
    case Unicycle extends Vehicle(1)
    case Bicycle  extends Vehicle(2)
    case Car      extends Vehicle(4)
~~~
Martin Odersky's avatar
Martin Odersky committed

- Enumeration cases that pass parameters have to use an explicit `extends` clause
Martin Odersky's avatar
Martin Odersky committed

Enumerations Are Shorthands for Classes and Objects
===================================================
Martin Odersky's avatar
Martin Odersky committed

The `Color` enum is expanded by the Scala compiler to roughly the following
structure:
Martin Odersky's avatar
Martin Odersky committed

~~~
  abstract class Color
  object Color with
    val Red     = Color()
    val Green   = Color()
    val Blue    = Color()
    val Magenta = Color()
    ...
~~~
Martin Odersky's avatar
Martin Odersky committed

(in reality, there are some more methods defined)