# Swift Switch Statements Explained with Syntax and Examples

Source: https://devdocs10.com/articles/swift/swift-switch-statements  
By Murat Bo · Published 2026-05-12 · DevDocs10 (https://devdocs10.com)

Swift `switch` statements are one of the language's most useful control flow features. They let you compare a value against multiple possible patterns and run different code depending on what matches. In Swift, `switch` is more powerful than it is in many other languages because it supports ranges, tuples, enums, value binding, and `where` clauses.

> **Quick answer:** A Swift `switch` statement checks a value against one or more `case` patterns and executes the first matching block. Unlike some languages, Swift switches must be exhaustive, do not fall through by default, and can match much more than exact values.

> **Difficulty:** Beginner
>
> **Helpful to know first:** You'll understand this better if you know basic Swift syntax, how variables store values, and simple types like `String`, `Int`, and `Bool`.

## 1. What Is Swift Switch Statements?

A `switch` statement is a control flow tool that chooses one code path from several possibilities. You give it a value, then define different `case` branches that describe what should happen for different matches.

- It compares one value against multiple possible matches.
- It must cover every possible case, either explicitly or with `default`.
- It does not automatically continue into the next case.
- It can match exact values, ranges, tuples, enums, and patterns.
- It is often clearer than a long chain of `if` and `else if` statements.

Swift `switch` is often compared with `if`/`else`. Use `if` when you have a small number of simple conditions. Use `switch` when you are matching one value against several known patterns or when clarity matters.

## 2. Why Swift Switch Statements Matters

`switch` matters because it makes branching logic easier to read and safer to maintain. Instead of writing several separate comparisons, you can organize all possible outcomes in one place.

It is especially useful when working with:

- User input such as commands, menu choices, or status text.
- Numeric ranges such as score bands or age groups.
- Enums, where Swift can help ensure all cases are handled.
- Tuples, where multiple values need to be matched together.
- Pattern matching, where you want concise but expressive logic.

Because Swift requires exhaustiveness, `switch` can also prevent logic gaps. This is a practical safety feature, not just syntax.

## 3. Basic Syntax

The basic idea is simple: provide a value after `switch`, then list possible `case` matches.

### Basic form

Here is the smallest useful example. This switch checks a day number and prints a matching message.

```swift
let day = 3

switch day {
case 1:
    print("Monday")
case 2:
    print("Tuesday")
case 3:
    print("Wednesday")
default:
    print("Another day")
}
```

Output (tested with Swift 6.4):

```text
Wednesday
```

Swift checks each case from top to bottom and runs the first one that matches. Because `day` is `3`, the output is `Wednesday`.

### Important rules

There are a few rules beginners should know immediately:

- Each `case` ends with a colon.
- Cases must be exhaustive, so include all possibilities or use `default`.
- You do not need `break` after each case.
- If you truly want fallthrough behavior, you must write `fallthrough` explicitly.

## 4. Step-by-Step Examples

### Example 1: Matching exact string values

This example matches a command entered by a user.

```swift
let command = "start"

switch command {
case "start":
    print("Starting the app")
case "stop":
    print("Stopping the app")
case "pause":
    print("Pausing the app")
default:
    print("Unknown command")
}
```

Output (tested with Swift 6.4):

```text
Starting the app
```

This is a clear replacement for multiple `if`/`else if` checks. It keeps all command options together in one readable block.

### Example 2: Matching multiple values in one case

You can match several values in a single branch by separating them with commas.

```swift
let letter = "a"

switch letter {
case "a", "e", "i", "o", "u":
    print("This is a vowel")
default:
    print("This is not a vowel")
}
```

Output (tested with Swift 6.4):

```text
This is a vowel
```

This is useful when several values should produce the same result.

### Example 3: Matching ranges

Swift switch statements can match ranges directly, which is one reason they are more powerful than many beginners expect.

```swift
let score = 87

switch score {
case 0...59:
    print("Fail")
case 60...69:
    print("Pass")
case 70...89:
    print("Good")
case 90...100:
    print("Excellent")
default:
    print("Invalid score")
}
```

Output (tested with Swift 6.4):

```text
Good
```

This keeps range-based logic concise and readable.

### Example 4: Matching tuples

A tuple switch can check multiple related values at once. Here, a coordinate is matched against different positions.

```swift
let point = (0, 5)

switch point {
case (0, 0):
    print("At the origin")
case (0, _):
    print("On the y-axis")
case (_, 0):
    print("On the x-axis")
default:
    print("Somewhere else")
}
```

Output (tested with Swift 6.4):

```text
On the y-axis
```

The underscore pattern means “ignore this value.” This lets you focus only on the part you care about.

### Example 5: Value binding with `let`

You can extract matched values directly inside a case. This is called value binding.

```swift
let point = (4, -2)

switch point {
case (let x, 0):
    print("On the x-axis at x = \(x)")
case (0, let y):
    print("On the y-axis at y = \(y)")
case (let x, let y):
    print("Point is at (\(x), \(y))")
}
```

Output (tested with Swift 6.4):

```text
Point is at (4, -2)
```

This allows the matching logic and the extracted values to stay together.

### Example 6: Using `where` in a case

A `where` clause adds an extra condition to a match.

```swift
let point = (3, 3)

switch point {
case (let x, let y) where x == y:
    print("The point is on the line x == y")
case (let x, let y):
    print("The point is at (\(x), \(y))")
}
```

Output (tested with Swift 6.4):

```text
The point is on the line x == y
```

This makes `switch` even more expressive when simple pattern matching is not enough.

## 5. Practical Use Cases

- Handling enum states such as loading, success, and failure in an app.
- Categorizing numeric input like grades, discounts, or temperature bands.
- Routing text commands in a command-line program.
- Matching tuple values such as coordinates, dimensions, or paired status codes.
- Parsing structured results where pattern matching is clearer than nested conditionals.
- Responding to different API result cases when modeled as enums with associated values.

## 6. Common Mistakes

### Mistake 1: Forgetting that a switch must be exhaustive

In Swift, every possible value must be handled. Beginners often write only the cases they expect and forget the rest.

**Problem:** This switch does not handle all possible values, so Swift reports an error such as `Switch must be exhaustive`.

```swift
let number = 2

switch number {
case 1:
    print("One")
case 2:
    print("Two")
}
```

**Fix:** Add a `default` case or explicitly cover every possible value.

```swift
let number = 2

switch number {
case 1:
    print("One")
case 2:
    print("Two")
default:
    print("Something else")
}
```

Output (tested with Swift 6.4):

```text
Two
```

The corrected version works because every remaining value now has a matching branch.

### Mistake 2: Expecting automatic fallthrough

In some languages, matching one case continues into the next case unless you add `break`. Swift does not work that way.

**Problem:** This code prints only the first message, because Swift stops after the first matching case unless `fallthrough` is written explicitly.

```swift
let grade = "A"

switch grade {
case "A":
    print("Excellent")
case "B":
    print("Good")
default:
    print("Other grade")
}
```

Output (tested with Swift 6.4):

```text
Excellent
```

**Fix:** Write each case as a complete branch. Use `fallthrough` only when you specifically want the next case's code to run.

```swift
let grade = "A"

switch grade {
case "A":
    print("Excellent")
    print("Top performance")
case "B":
    print("Good")
default:
    print("Other grade")
}
```

Output (tested with Swift 6.4):

```text
Excellent
Top performance
```

The corrected version works because all logic for the `"A"` case is kept in the same branch.

### Mistake 3: Using `if` logic where pattern matching is clearer

Beginners sometimes write long, repetitive conditional chains when a switch would be simpler and easier to maintain.

**Problem:** This approach works, but it duplicates the same variable comparison over and over and becomes harder to read as the number of branches grows.

```swift
let httpStatus = 404

if httpStatus == 200 {
    print("OK")
} else if httpStatus == 404 {
    print("Not Found")
} else if httpStatus == 500 {
    print("Server Error")
} else {
    print("Unknown status")
}
```

Output (tested with Swift 6.4):

```text
Not Found
```

**Fix:** Use a `switch` when one value is being compared against multiple possibilities.

```swift
let httpStatus = 404

switch httpStatus {
case 200:
    print("OK")
case 404:
    print("Not Found")
case 500:
    print("Server Error")
default:
    print("Unknown status")
}
```

Output (tested with Swift 6.4):

```text
Not Found
```

The corrected version works because the branching logic is grouped around a single matched value.

### Mistake 4: Misusing `fallthrough`

`fallthrough` does not re-check the next case's pattern. It simply continues execution into the next case block.

**Problem:** This code may produce surprising output because the next case runs even though its pattern was not matched.

```swift
let number = 1

switch number {
case 1:
    print("One")
    fallthrough
case 2:
    print("Two")
default:
    print("Other")
}
```

Output (tested with Swift 6.4):

```text
One
Two
```

**Fix:** Prefer grouped cases or separate logic unless you truly need forced continuation.

```swift
let number = 1

switch number {
case 1, 2:
    print("One or Two")
default:
    print("Other")
}
```

Output (tested with Swift 6.4):

```text
One or Two
```

The corrected version works because it expresses the intended match directly instead of forcing execution into another case.

## 7. Best Practices

### Practice 1: Prefer switch when matching one value many ways

If your logic repeatedly compares the same value, `switch` is often easier to read than repeated conditionals.

```swift
let statusCode = 201

switch statusCode {
case 200:
    print("OK")
case 201:
    print("Created")
case 400:
    print("Bad Request")
default:
    print("Other status")
}
```

Output (tested with Swift 6.4):

```text
Created
```

This keeps related branches together and makes future updates simpler.

### Practice 2: Use grouped cases for shared behavior

When multiple values should trigger the same result, group them into one case instead of duplicating code.

```swift
let character = "e"

switch character {
case "a", "e", "i", "o", "u":
    print("Vowel")
default:
    print("Consonant or other")
}
```

Output (tested with Swift 6.4):

```text
Vowel
```

This reduces duplication and makes the intention obvious.

### Practice 3: Use pattern matching instead of nested conditions

Tuple matching and value binding can replace complex nested logic with a cleaner structure.

```swift
let coordinate = (0, -7)

switch coordinate {
case (0, let y):
    print("On the y-axis at \(y)")
case (let x, 0):
    print("On the x-axis at \(x)")
default:
    print("Elsewhere")
}
```

Output (tested with Swift 6.4):

```text
On the y-axis at -7
```

This style is expressive and matches the shape of the data directly.

### Practice 4: Avoid unnecessary `default` when switching on enums you fully control

When switching over an enum, handling each case explicitly can make future changes safer. If a new enum case is added later, the compiler can point out missing branches.

```swift
enum ConnectionState {
    case disconnected
    case connecting
    case connected
}

let state = ConnectionState.connecting

switch state {
case .disconnected:
    print("Offline")
case .connecting:
    print("Connecting...")
case .connected:
    print("Online")
}
```

Output (tested with Swift 6.4):

```text
Connecting...
```

This gives you better compiler help than hiding unhandled cases in a broad `default`.

## 8. Limitations and Edge Cases

- `switch` handles one matched value expression, though that expression can be a tuple or other compound value.
- Case order matters. Swift stops at the first matching case.
- `fallthrough` does not test the next pattern again; it only continues execution.
- A very large `switch` can become hard to maintain, especially when business logic in each case grows too large.
- Using `default` too eagerly with enums can hide new cases that should be handled explicitly.
- Range matching is powerful, but overlapping ranges can make earlier cases capture values you intended for later ones.
- Some beginners think `switch` is only for integers or strings, but Swift supports much richer pattern matching.

## 9. Practical Mini Project

This small program classifies a weather temperature into human-friendly categories. It uses range matching and provides a complete working example.

```swift
let temperature = 18

switch temperature {
case ...0:
    print("Freezing")
case 1...10:
    print("Cold")
case 11...20:
    print("Mild")
case 21...30:
    print("Warm")
default:
    print("Hot")
}
```

Output (tested with Swift 6.4):

```text
Mild
```

This example shows a practical pattern you might use in a console tool, data-processing script, or beginner app logic. The switch is readable because each range clearly maps to one outcome.

## 10. Key Points

- A Swift `switch` compares one value against multiple patterns.
- Swift switches must be exhaustive, so all possible cases must be handled.
- Cases do not fall through automatically in Swift.
- You can match exact values, multiple values, ranges, tuples, and patterns with bound values.
- `where` clauses add extra conditions to pattern matches.
- `switch` is often cleaner than repeated `if`/`else if` checks when matching one value many ways.

## 11. Practice Exercise

Build a switch statement that classifies a numeric month into a season.

- Create a constant named `month`.
- Use a `switch` statement to print the season.
- Treat months 12, 1, and 2 as Winter.
- Treat months 3, 4, and 5 as Spring.
- Treat months 6, 7, and 8 as Summer.
- Treat months 9, 10, and 11 as Autumn.
- Print `Invalid month` for values outside 1 through 12.

**Expected output:** If `month` is `7`, the program should print `Summer`.

**Hint:** Group multiple month values in the same `case`.

```swift
let month = 7

switch month {
case 12, 1, 2:
    print("Winter")
case 3, 4, 5:
    print("Spring")
case 6, 7, 8:
    print("Summer")
case 9, 10, 11:
    print("Autumn")
default:
    print("Invalid month")
}
```

Output (tested with Swift 6.4):

```text
Summer
```

## 12. Final Summary

Swift `switch` statements are more than a basic branching tool. They provide a structured way to handle multiple possibilities while supporting powerful pattern matching features such as ranges, tuples, value binding, and `where` clauses. Because switches must be exhaustive and do not fall through automatically, they also help you write safer and clearer code.

As you continue learning Swift, practice replacing long `if`/`else if` chains with `switch` where appropriate. A great next step is learning how `switch` works with enums and associated values, because that is where Swift's pattern matching becomes especially powerful.
