Associated values for enumerations in Swift

Associated values take Swift enumerations to the next level in expressive power. They let you associate a custom value (or values) with each enumeration case.

Here are some unique qualities of associated values:

  1. Each enumeration case has zero or more associated values.
  2. The associated values for each enumeration case have their own data type.
  3. You can define associated values with label names like you would for named function parameters.

An enumeration can have raw values or associated values, but not both.

Let’s say you took your money to the bank and deposited it. You could then go to an ATM and withdraw your money:

var balance = 100
func withdraw(amount: Int) {
    balance -= amount

The ATM will never let you withdraw more than you put in, so it needs a way to let you know whether the transaction was successful. You can implement this as an enumeration with associated values:

enum WithdrawalResult {
    case success(newBalance: Int)
    case error(message: String)

Each case has a required value to go along with it. For the success case, the associated Int will hold the new balance; for the error case, the associated String will have some kind of error message.

Then you can rewrite the withdraw function to use the enumeration cases:

func withdraw(amount: Int) -> WithdrawalResult {
    if amount <= balance {
        balance -= amount
        return .success(newBalance: balance)
    } else {
        return .error(message: "Not enough money!")

Now you can perform a withdrawal and handle the result:

let result = withdraw(amount: 99)
switch result {
    case .success(let newBalance):
        print("Your new balance is: \(newBalance)")
    case .error(let message):

Notice how you used let bindings to read the associated values. Associated values aren’t properties you can access freely, so you’ll need bindings like these to read them. Remember that the newly bound constants newBalance and message are local to the switch cases. They aren’t required to have the same name as the associated values, although it’s common practice to do so.

You’ll see "Your new balance is: 1" printed out in the debug console.