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.
