Skip to content

Control Flow

Swift provides several ways to control the flow of execution, including conditionals and loops.

Syntax Rules

Across all control flow structures in Swift:

  • Braces {}: Braces are mandatory for all blocks (if, for, while, switch, etc.), including single-line blocks.
  • Parentheses (): Parentheses are optional and usually omitted for all conditions (like in if or while).
  • Semicolons ;: Semicolons are optional (at the end of statements) everywhere in Swift, unless you're packing multiple statements onto one line.

Comparison and Logical Operators

Control flow often relies on comparing values or combining conditions.

Comparison Operators

OperatorDescription
==Equal to
!=Not equal to
>Greater than
<Less than
>=Greater than or equal to
<=Less than or equal to

Logical Operators

OperatorDescription
&&Logical AND (both conditions must be true)
||Logical OR (at least one condition must be true)
!Logical NOT (inverts a boolean value)

Conditionals

If Statement

Standard if, else if, and else blocks.

swift
let score = 85

if score >= 90 {
    print("Grade: A")
} else if score >= 80 {
    print("Grade: B")
} else {
    print("Grade: C")
}

Ternary Operator

The ternary conditional operator is a concise alternative to an if-else statement. It takes the form question ? answerIfTrue : answerIfFalse.

swift
let score = 85
let result = score >= 50 ? "Pass" : "Fail"
print(result) // Pass

Switch Statement

Swift switch statements are powerful and must be exhaustive (covering all possibilities or using a default case).

  • No Implicit Fallthrough: Swift automatically exits the switch once a match is found. You don't need to write break at the end of every case.
  • Flexible Matching: Cases can match multiple values (separated by commas), tuples, and ranges (e.g., 1...3 for numbers 1 through 3).
swift
let count = 5

switch count {
case 0:
    print("None")
case 1...3: // Range matching
    print("A few")
case 4, 5, 6: // Multiple value matching
    print("Several")
default:
    print("Many")
}

Cases can also use a where clause to check for additional conditions.

swift
let number = 10

switch number {
case let x where x % 2 == 0:
    print("\(x) is even")
default:
    print("It's odd")
}

Loops

For-In Loop

Used to iterate over ranges, arrays, dictionaries, or sets.

swift
// Iterate over a range
for i in 1...5 {
    print(i) // 1, 2, 3, 4, 5
}

// Half-open range (excludes the upper bound)
for i in 1..<5 {
    print(i) // 1, 2, 3, 4
}

If you do not need each value from a sequence, use an underscore _ in place of a variable name to ignore the values.

swift
for _ in 1...3 {
    print("Hello")
}

To skip values or count backwards, use the stride(from:to:by:) or stride(from:through:by:) functions instead of a standard range.

swift
for i in stride(from: 0, to: 10, by: 2) {
    print(i) // 0, 2, 4, 6, 8
}

While Loops

  • while: Evaluates the condition before each pass.
  • repeat-while: Evaluates the condition after each pass (guarantees at least one execution).
swift
var count = 5
while count > 0 {
    print(count)
    count -= 1
}

repeat {
    print("Executed once")
} while false

Control Transfer

Control transfer statements change the order of execution. The break statement ends a loop immediately, and continue skips to the next iteration of the loop.

When dealing with nested loops, you can use statement labels to specify exactly which loop to break or continue. Prefix a loop with a label name and use that same label with your break statement.

swift
outerLoop: for i in 1...3 {
    for j in 1...3 {
        if i == 2 && j == 2 {
            break outerLoop
        }
        print("i:\(i), j:\(j)")
    }
}