Model your program

Swift Enumerations

An introduction to enumerations in Swift: how to group options under a type, use them in switch statements, and assign raw values you read with rawValue.

This tutorial belongs to the Swift series

An enumeration groups a set of related options under one name.

Example:

enum Animal {
    case dog
    case cat
    case mouse
    case horse
}

Animal is now a type, and a value of that type can only be one of the four cases listed. Not a string, not a number, not a typo. If you try Animal.bird, the compiler tells you Type 'Animal' has no member 'bird'.

This is why I prefer enums over strings for anything with a fixed set of options: the compiler checks every value for you.

You can declare a variable of type Animal:

var animal: Animal

and assign a case later. Since Swift already knows the type, you can skip the Animal. prefix and write just the dot:

var animal: Animal
animal = .dog

You can also write all the cases on one line:

enum Animal {
    case dog, cat, mouse, horse
}

Enums and switch

Enumerations and switch go together. Swift requires a switch to cover every case, so with an enum you can list them all and skip default:

enum Animal {
    case dog
    case cat
    case mouse
    case horse
}

let animal = Animal.dog

switch animal {
case .dog: print("dog")
case .cat: print("cat")
default: print("another animal")
}

Here we handle two cases and send the other two to default. If you remove default, the compiler reminds you that .mouse and .horse are not handled. Add a case to the enum later and every switch without a default fails to compile until you handle it. That’s a safety net you don’t get with strings.

Raw values

By default a case is just a name. You can attach a value to each case by giving the enum a type. These are called raw values:

enum Animal: Int {
    case dog = 1
    case cat = 2
    case mouse = 3
    case horse = 4
}

Raw values can be integers, strings, or characters. All cases must use the same type.

You read the raw value with the rawValue property:

enum Animal: Int {
    case dog = 1
    case cat = 2
    case mouse = 3
    case horse = 4
}

var animal: Animal
animal = .dog

animal.rawValue // 1

You can also go the other way, from a raw value to a case:

Animal(rawValue: 2) // Optional(Animal.cat)
Animal(rawValue: 9) // nil

The result is an optional, because not every number matches a case. This is handy when the value comes from outside your program, like a JSON file or a database, and you want to turn it into something the compiler can check.

Enums are value types

Enumerations are value types, like structures. When you pass one to a function, return it, or assign it to another variable, Swift copies it.

Lesson completed