Enumerations: custom types for storing a group of related values

Syntax:

enum theEnum {
  case someCase
}

Unlike enumerations in C, Swift Enumerations are a first-class type that do not simply assign names to a set of integers. It is possible to assign a raw value to each member, but that's not required. If provided, the raw value must be one of Character, String, Floating point, or Integer value.

enum Lake {
  case Erie
  case Huron
  case Michigan
  case Ontario
  case Superior
}

/* Members can also all be defined on the same line when separated by commas */
enum Ocean {
  case Arctic, Atlantic, Indian, Pacific, Southern
}

var waterBody = Ocean.Atlantic
/* Once a variable knows the type of enumeration it's working with, subsequent updates can use dot syntax */
waterBody = .Pacific

Raw Values

While not required, default raw values can be assigned to each enumeration member, if necessary. Every raw value must be of the same type, and must be unique within the enumeration. If the Integer type is used, values will auto-increment if no value is specified for a given member.

enum Lake: Int {
  case Erie = 1, Huron, Michigan, Ontario, Superior
}

let greatLake = Lake.Michigan.toRaw()
// greatLake is equal to 3

let someLake = Lake.fromRaw(6)
/* Because fromRaw might not find a value, it returns an optional (Lake?). In this case, someLake is equal to nil */

Associated Types

Aside from a raw value, enumeration members can also accept ANY type as an Associated Value. Each member of an enumeration can have a different type as its associated value, and the associated values (but not the type) can be different every time you reference that member in your code. When checking the values, you can retrieve them as either constants or variables. If they will ALL be constant or variable, then that only needs to be specified once (Version 2)

enum Entertainment {
  case Movie(String, String, Int)
  case TVShow(String, Int, Int, String)
}

var media = Entertainment.movie("Citizen Kane", "Orson Welles", 1941)

// Version 1
switch media {
  case .Movie(let title, let director, var releaseYear):
    println("Movie: Title = \(title), Director = \(director), Year = \(releaseYear)")
  case .TVShow(let title, let season, let episode):
    println("TV Show: Title = \(title), Season \(season), Episode \(episode)")
}
// prints Movie: Title = Citizen Kane, Director = Orson Welles, Year = 1941

// Version 2
switch media {
  case let .Movie(title, director, releaseYear):
    println("Movie: Title = \(title), Director = \(director), Year = \(releaseYear)")
  case let .TVShow(title, season, episode):
    println("TV Show: Title = \(title), Season \(season), Episode \(episode)")
}

Computed Values

Below is an example that includes a computed value as part of the enumeration:

enum StopLight {
  case Green
  case Red(Int)
  init() {
    self = Green
  }
  var status: String {
    switch self {
      case Green:
        return "clear sailing"
      case Red(let seconds):
        return "gotta wait \(seconds) seconds"
    }
  }
}

var lightStatus = StopLight()
println("Light shows \(lightStatus.status)")
// prints Light shows clear sailing
lightStatus = .Red(5)
println("Light now shows you \(lightStatus.status)")
// prints Light now shows you gotta wait 5 seconds