Control Flow

7.1 if and guard

let temp = 25
if temp > 30 {
    print("Hot")
} else if temp > 15 {
    print("Pleasant")
} else {
    print("Cold")
}

let label = if temp > 20 { "warm" } else { "cool" }   // if expression (Swift 5.9)

func process(age: Int?) {
    guard let age, age >= 18 else { return }
    print("Adult: \(age)")
}

7.2 switch (Exhaustive and Powerful)

No implicit fallthrough (no break needed). Use fallthrough explicitly. Switches must be exhaustive.

let value = 42
switch value {
case 0:
    print("zero")
case 1..<10:
    print("single digit")
case 10, 20, 30:
    print("round number")
case let x where x.isMultiple(of: 2):
    print("even: \(x)")
default:
    print("other")
}

let point = (2, 0)
switch point {
case (0, 0): print("origin")
case (_, 0): print("on the x-axis")
case (0, _): print("on the y-axis")
case (-2...2, -2...2): print("inside the box")
case let (x, y): print("at \(x), \(y)")
}

let grade = switch value {        // switch expression (Swift 5.9)
case 90...: "A"
case 80..<90: "B"
default: "C"
}

7.3 Loops

for i in 1...5 { print(i) }
for i in stride(from: 0, to: 10, by: 2) { print(i) }       // 0 2 4 6 8
for i in stride(from: 10, through: 0, by: -5) { print(i) }
for (index, fruit) in ["apple", "banana"].enumerated() { print(index, fruit) }
for (key, value) in ["a": 1, "b": 2] { print(key, value) }
for _ in 0..<3 { print("hi") }
for n in 1...20 where n.isMultiple(of: 5) { print(n) }    // filtered loop

var count = 3
while count > 0 { count -= 1 }
repeat { count += 1 } while count < 3                     // do-while

outer: for i in 1...3 {                                    // labeled statements
    for j in 1...3 {
        if j == 2 { continue outer }
        if i == 3 { break outer }
        print(i, j)
    }
}

7.4 Control Transfer and Assertions

continue, break, fallthrough, return, throw.

assert(condition, "msg") checks in debug builds only. precondition(...) checks in release builds too. fatalError("msg") always crashes (it returns Never).

7.5 Availability Checks

if #available(iOS 17, macOS 14, *) {
    // use new APIs
} else {
    // fallback
}
if #unavailable(iOS 16) { /* ... */ }
@available(iOS 16.0, *)
func modernFeature() {}