EthicsComputerCourses
Join training +91 90532 10052

if, guard & Loops

Swift · Lesson 9 of 30 Beginner 7 min read Updated

So far every program ran from the first line to the last. Real programs make decisions ("if the marks are above 33, print Pass") and repeat work ("for every student in the class, print a report card"). Statements that change the order in which code runs are called control flow.

In this lesson you will learn Swift's decision makers, if, guard and a first look at switch, and its loops: for-in, while and repeat-while. You will also learn break and continue, and how Swift's guard keeps functions tidy.

if, else if and else

An if statement runs a block only when its condition is true. Add else if for more conditions and else for "everything else". The condition must be a real Bool; Swift does not treat 0 or an empty string as false. The braces are always required, even for one line.

Swift
let marks = 76

if marks >= 90 {
    print("Grade A+")
} else if marks >= 75 {
    print("Grade A")
} else if marks >= 33 {
    print("Pass")
} else {
    print("Fail")
}
Output
Grade A

Swift checks the conditions from top to bottom and runs only the first block whose condition is true. Since 76 >= 90 is false and 76 >= 75 is true, it prints "Grade A" and skips the rest.

if and switch as expressions

Since Swift 5.9, if and switch can also produce a value, so you can assign their result directly. Each branch must give a value of the same type.

Swift
let temperature = 41
let advice = if temperature >= 40 {
    "Stay indoors"
} else if temperature >= 30 {
    "Carry water"
} else {
    "Enjoy the weather"
}
print(advice)

let hour = 14
let greeting = switch hour {
case 5..<12: "Good morning"
case 12..<17: "Good afternoon"
default: "Good evening"
}
print(greeting)
Output
Stay indoors
Good afternoon

A switch compares one value against several patterns, here ranges of hours. It must be exhaustive: every possible value must match some case, which is why there is a default. Unlike C and Java, Swift's switch does not fall through to the next case, so there is no break to forget. You will use switch much more in Enums & switch.

guard: exit early

guard checks a condition that must be true for the rest of the code to make sense. If the condition is false, the else block runs and must leave the current scope, with return in a function or continue/break in a loop. You will learn functions properly in the next section; for now just notice the shape.

Swift
func bookTicket(age: Int, seatsLeft: Int) {
    guard age >= 5 else {
        print("Children under 5 travel free")
        return
    }
    guard seatsLeft > 0 else {
        print("Sorry, the train is full")
        return
    }
    print("Ticket booked for age \(age)")
}

bookTicket(age: 3, seatsLeft: 10)
bookTicket(age: 30, seatsLeft: 0)
bookTicket(age: 30, seatsLeft: 4)
Output
Children under 5 travel free
Sorry, the train is full
Ticket booked for age 30

With guard, the error cases are handled at the top and the "happy path" stays at the left edge, not buried inside nested if blocks. The compiler checks that every guard else block really exits. guard let also unwraps optionals, which you will use a lot in Optionals & Unwrapping.

for-in loops

A for-in loop runs once for each item in a sequence: a range, an array, a dictionary or a string. Use stride to count in steps, where to skip items, and _ when you do not need the loop variable.

Swift
for n in 1...3 {
    print("7 x \(n) = \(7 * n)")
}

let years = Array(stride(from: 2020, through: 2026, by: 2))
print(years)

var multiplesOfThree: [Int] = []
for n in 1...10 where n.isMultiple(of: 3) {
    multiplesOfThree.append(n)
}
print(multiplesOfThree)

var stars = ""
for _ in 1...5 {
    stars += "*"
}
print(stars)
Output
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
[2020, 2022, 2024, 2026]
[3, 6, 9]
*****

stride(from:through:by:) includes the end value; stride(from:to:by:) stops before it. A negative step counts down: stride(from: 10, through: 0, by: -5) gives 10, 5, 0. To count down by one, you can also write for n in (1...5).reversed().

while and repeat-while

A while loop checks its condition before each run, so it may run zero times. A repeat-while loop checks after each run, so it always runs at least once. Use them when you do not know in advance how many times to repeat.

Swift
var savings = 0
var week = 0
while savings < 1000 {
    week += 1
    savings += 150
}
print("Week \(week): ₹\(savings)")

var attempts = 0
repeat {
    attempts += 1
    print("Sending OTP, attempt \(attempts)")
} while attempts < 3
Output
Week 7: ₹1050
Sending OTP, attempt 1
Sending OTP, attempt 2
Sending OTP, attempt 3

Priya saves ₹150 a week. After 6 weeks she has ₹900, still below 1000, so the loop runs a seventh time and stops at ₹1050. Always make sure something inside a while loop moves it towards its end, or it will run forever.

break, continue and labels

continue skips the rest of the current pass and moves to the next item. break leaves the loop completely. With nested loops, give the outer loop a label and write break label to leave both at once.

Swift
let orders = [250, -1, 400, 0, 999, 120]
var total = 0
for amount in orders {
    if amount <= 0 { continue }   // skip invalid entries
    if amount > 900 { break }     // stop at a suspicious order
    total += amount
}
print(total)

let shelves = [["Maths", "Hindi"], ["Physics", "Atlas", "Biology"], ["Atlas"]]
search: for (index, books) in shelves.enumerated() {
    for book in books where book == "Atlas" {
        print("Found Atlas on shelf \(index + 1)")
        break search
    }
}
Output
650
Found Atlas on shelf 2

The first loop adds 250 and 400, skips -1 and 0, and stops at 999, so 120 is never added. In the second, break search ends both loops as soon as the first atlas is found, so shelf 3 is never checked.

Common mistakes

  • Using a number as a condition. if count { } does not compile; write if count > 0.
  • A guard that does not exit. The else block must return, break, continue or throw.
  • Off-by-one loops. 0...array.count goes one past the end; use 0..<array.count or array.indices.
  • Endless while loops. Change the variable the condition depends on inside the loop.

Key points

  • if, else if and else choose a branch; conditions must be Bool, and braces are required.
  • if and switch can be expressions that produce a value (Swift 5.9 and later).
  • guard condition else { exit } handles bad cases early and keeps the main path flat.
  • for-in loops over ranges and collections; stride steps, where filters and _ ignores the value.
  • while checks first; repeat-while always runs at least once.
  • continue skips one pass, break ends a loop, and labels let you break out of nested loops.

Exercise

Print the bus fare for passengers aged 2, 8, 35, 64 and 70. Fares: under 5 free, 5 to 11 half fare, 60 and above a 40 percent senior discount, everyone else full fare of ₹200. Use a for-in loop and an if expression to choose each fare, and keep a running total. Skip any age below 0 with continue.

Show solution
Swift
let ages = [2, 8, 35, 64, 70]
var total = 0

for age in ages {
    if age < 0 { continue }
    let fare = if age < 5 {
        0
    } else if age < 12 {
        100
    } else if age >= 60 {
        120
    } else {
        200
    }
    total += fare
    print("Age \(age): ₹\(fare)")
}
print("Total: ₹\(total)")
Output
Age 2: ₹0
Age 8: ₹100
Age 35: ₹200
Age 64: ₹120
Age 70: ₹120
Total: ₹540

Each branch of the if expression gives an Int, so fare is an Int. The senior fare is 200 minus 40 percent, which is 120.

Quick Quiz

1. What happens if a guard condition is false?

2. How many times does repeat { } while false run its body?

3. Which loop prints 10, 8, 6?

4. Does a Swift switch case fall through to the next case automatically?

Learn Swift with a mentor

Free lessons get you started. Our Mobile App Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call