What is the difference between if case, guard case, and switch on an enum?

1.2.5 · L2 · Interview

Predict first

Does this compile?

enum Shape { case circle(Double), square(Double) }

func name(_ s: Shape) -> String {
    switch s {
    case .circle: return "circle"
    }
}
  • Yes
  • No

Mental model. switch is a full audit of every case. if case is checking one box on the form and walking away.

switch is exhaustive — the compiler requires every case (or a default/@unknown default). Use it when every case matters or when you want the compiler to tell you when a new case is added.

if case let .foo(x) matches a single pattern without requiring exhaustiveness. guard case is the same but binds for the rest of the scope and must exit.

Rule of thumb: payload extraction for one case → if case. Branching on the whole state machine → switch.

switch must be exhaustive. if case and guard case match one pattern and let you ignore the rest.

Common traps

  • Using if case on a state machine. You silently ignore new cases when the enum grows. switch is the safer default.
  • Forgetting @unknown default for non-frozen enums. SDK enums can gain cases; a plain default compiles but hides the change.

They might follow up with

  • What is if case .some(let x)? A pattern match on the optional enum — the same thing as if let x.
  • Can you match multiple patterns in one case? Yes: case .a, .b: and value bindings with where.

Related questions

  • 1.2.2 Why can switch on an Optional use .none / .some and also nil?
  • 1.7.1 What is the purpose of access control? List the levels.

← What does guard buy you beyond if?   How does optional chaining (a?.b?.c) actually work? →