Swift Enumerations

An enumeration (enum) defines a group of related named values. Instead of using raw strings or numbers that could be mistyped, an enum gives each option a safe, descriptive name. Swift enums are powerful — they can carry data, have methods, and work with switch statements beautifully.

The Traffic Signal Analogy


┌──────────────────────────────────────────────────┐
│  Without enum:   With enum:                      │
│  var light = 1   var light = TrafficLight.red    │
│  var light = 2   var light = TrafficLight.yellow │
│  var light = 3   var light = TrafficLight.green  │
│                                                  │
│  The enum version is clear and cannot be         │
│  set to an invalid value like 99.                │
└──────────────────────────────────────────────────┘

Defining an Enum

enum Direction {
    case north
    case south
    case east
    case west
}

var heading = Direction.north
heading = .east   // shorthand when type is known
print(heading)    // east

Using Enum with Switch

let move = Direction.south

switch move {
case .north:
    print("Going up")
case .south:
    print("Going down")
case .east:
    print("Going right")
case .west:
    print("Going left")
}
// Going down

Switch and enums are a natural pair. Swift forces you to handle every case, so no option is ever forgotten.

Raw Value Enums

enum Planet: Int {
    case mercury = 1
    case venus
    case earth
    case mars
}

print(Planet.earth.rawValue)     // 3
let p = Planet(rawValue: 1)      // mercury (optional)
print(p ?? "Unknown")            // mercury

Raw values assign a concrete value (Int, String, etc.) to each case. Swift automatically increments integer raw values from the starting point.

String Raw Values

enum Season: String {
    case spring = "Spring"
    case summer = "Summer"
    case autumn = "Autumn"
    case winter = "Winter"
}

let current = Season.winter
print(current.rawValue)   // Winter

Associated Values – Enums That Carry Data

enum PaymentMethod {
    case cash(amount: Double)
    case card(last4Digits: String)
    case upi(id: String)
}

let payment = PaymentMethod.card(last4Digits: "4242")

switch payment {
case .cash(let amount):
    print("Paid ₹\(amount) in cash")
case .card(let digits):
    print("Card ending in \(digits)")
case .upi(let id):
    print("UPI to \(id)")
}
// Card ending in 4242

Associated Values Diagram


┌──────────────────────────────────────────────────────┐
│  PaymentMethod enum                                  │
│                                                      │
│  .cash  →  carries a Double (the amount)             │
│  .card  →  carries a String (last 4 digits)          │
│  .upi   →  carries a String (UPI ID)                 │
│                                                      │
│  Each case is a mini data container.                 │
└──────────────────────────────────────────────────────┘

Enums with Methods

enum Weekday {
    case monday, tuesday, wednesday, thursday, friday
    case saturday, sunday

    func isWeekend() -> Bool {
        return self == .saturday || self == .sunday
    }
}

let today = Weekday.saturday
print(today.isWeekend())   // true

Recursive Enums

indirect enum MathExpression {
    case number(Int)
    case add(MathExpression, MathExpression)
}

func evaluate(_ expr: MathExpression) -> Int {
    switch expr {
    case .number(let n):
        return n
    case .add(let a, let b):
        return evaluate(a) + evaluate(b)
    }
}

let expr = MathExpression.add(.number(3), .number(7))
print(evaluate(expr))   // 10

The indirect keyword allows an enum case to reference the same enum type inside itself. This is useful for building tree structures like math expressions or file systems.

Leave a Comment

Your email address will not be published. Required fields are marked *