Advanced and Practical Enum usage in Swift

Enum values

released Fri, 01 Mar 2019
Swift Version 5.0

Enum values

Sometimes may want to have a value assigned to each enum case. This is useful if the enum itself indeed relates to something which can be expressed in a different type. C allows you to assign numbers to enum cases. Swift gives you much more flexibility here:

// A pretty useless enum
enum Binary {
  case zero = 0
  case one = 1

// You can also map to strings
enum House: String {
    case baratheon = "Ours is the Fury"
    case greyjoy = "We Do Not Sow"
    case martell = "Unbowed, Unbent, Unbroken"
    case stark = "Winter is Coming"
    case tully = "Family, Duty, Honor"
    case tyrell = "Growing Strong"

// Or to floating point (also note the fancy unicode in enum cases)
enum Constants: Double {
    case π = 3.14159
    case e = 2.71828
    case φ = 1.61803398874
    case λ = 1.30357

For String and Int types, you can even omit the values and the Swift compiler will do the right thing:

// mercury = 1, venus = 2, ... neptune = 8
enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune

// north = "north", ... west = "west"
enum CompassPoint: String {
    case north, south, east, west

Swift supports the following types for the value of an enum:

  • Integer
  • Floating Point
  • String
  • Boolean

You can support more types by implementing a specific protocol.

If you want to access the values, you can do so with the rawValue property:

let bestHouse = House.stark
// prints "Winter is coming"

However, there may also be a situation where you want to construct an enum case from an existing raw value. In that case, there's a special initializer for enums:

enum Movement: Int {
    case left = 0
    case right = 1
    case top = 2
    case bottom = 3
// creates a movement.Right case, as the raw value for that is 1
let rightMovement = Movement(rawValue: 1)

If you use the rawValue initializer, keep in mind that it is a failable initializer, i.e. you get back an Optional, as the value you're using may not map to any case at all, say if you were to write Movement(rawValue: 42).