← All topics/Swift language features

Question 2

Optionals: guard let, if let, chaining, nil coalescing

How do you choose between guard let, if let, optional chaining, and nil coalescing for clarity and safety? When would you avoid force-unwraps?

Answer outline

Use guard let when nil means early exit: invalid state, a failed precondition, or nothing to do. The rest of the scope then works with a non-optional binding and the happy path stays unindented.

Use if let when both branches matter and nil is a normal outcome rather than a failure.

Optional chaining (?.) short-circuits a chain of property and method calls at the first nil. Combine it with nil coalescing (??) to supply a default value at the end.

Avoid force unwrapping (!) in production paths. Reserve it for cases where nil is a programmer error you would rather crash on, such as outlets that the storyboard always connects.

Principles

  • ?? supplies a default, but an explicit nil check is clearer when the nil case changes behavior.
  • Optional map and flatMap compose transformations without a pyramid of if let chains.
  • guard let handles the failure case first, so the code below it reads straight through with a non-optional binding.
  • Force unwrap only when nil would be a programmer error and a crash is the outcome you want.
guard let vs if let
func displayName(for user: User?) -> String {
    guard let user else { return "Guest" }
    return user.name
}

func subtitle(for item: Item?) -> String? {
    if let item {
        return item.title
    }
    return nil
}

The second line treats an empty name as missing, so ?? supplies the default in both cases:

Chaining and coalescing
let label = user?.profile?.displayName?.trimmingCharacters(in: .whitespaces)
let text = (label?.isEmpty == false ? label : nil) ?? "Unknown"