Enums and Switches
OCaml programmers rejoice–you'll be back in 3110. For everyone else, don't worry this won't be anything too special (until the advanced sections).
In programming, you will sometimes need to represent a set of states. There are multiple ways to do this, but you will most often see it implemented as a subset of integers that correspond to a specific state–usually denoted in constants. Below we will model what college someone is in using said technique:
This works fine if done properly. There is a concern here that the college
field is technically Int
; we can pass any integer into the college
field but it only makes sense if it is an integer that is contained in the constants predefined. For example, the following code would break our example:
We don't have a -1
college, so if we ever use this object later, we will have difficulty discerning what that means. In python, we would fix this with assert statements and/or preconditions. This is fine and works in Swift too, but we have a better alternative. Instead of using integers to represent a data type, let's just make a new data type! This is where enums
come; an enumeration type; a type where all valid states are distinguished.
If we are creating a basic enum, we use the syntax:
So for our college example, we could do something like...
We can think of each of these states as constructors for a state, so the state constructors are a member of the type itself. In lay-man terms, we can access a state like this:
If we are assigning a state somewhere that expects an enum, we can forgo the type. I.e. if we are assigning to a variable or a function, that already has the college type (it is explicitly typed instead of inferred) we just write .<state>
:
Switch Statements
Another great reason to use enums is switch statements–a very simple version of pattern matching. You can also think of this as a simplification for doing a lot of if-else statements. We will examine how to use switch-statements through an example:
With our students defined in the previous section, let's say we are trying to figure out their graduation requirements. We will build a function that takes in a school, and returns the requirements. For sake of laziness, if the school is one not explicitly listed above, we will just return the swim test. Here's how we would do this with if-else statements:
This is fine and dandy, but there's a lot of writing, I have to make sure my if-else statements are correct, and I often forget cases when doing more complicated things like this. We can use switch statements to fix this. To use a switch we use the syntax:
So, for the above example, we would write it like:
Notice that we use default
to catch cases that have not been handled.
Switch statements can work for many types, but they work especially well with enums because they have such clear patterns that can be handled in unique manners. Moreover, if we ever update our enum
to include additional states, switches can let us know when we do not cover this case.
Literals
You want to associate (sorry this is a poor word choice–you'll see why later) your enums with certain values. For example, with the College
example, we may want to print the college someone is going to:
It's cool that Swift will allow us to print the state name directly, but seeing as we named our college kind of gross abbreviations, this doesn't necessarily make sense. If want to change this, we can have our enum
conform to a type, and directly assign values.
If you ever need to access these literal values, you can use the rawValue
property:
You can also use raw values as an initializer:
Advanced Topics
Enums with Associated Values are a very powerful tool that mimic OCaml types. This can be hard to employ and is not very helpful for UI until you get to Networking!
Enums with Associated ValuesIndirect enums are for those that want to Fun
ctional. This is a very weird, cool, powerful, and crazy tool. Not really sure when you'd ever use this in UI though ¯_(ツ)_/¯.
Last updated