It’s a trap!

Swift enums and the danger of the default case

Toby O'Connell
2 min readFeb 15, 2024

--

Context

A lot of the time in Swift we will use enums to define bits of state within an app. The beauty of enums is that they represent a complete set of possible options. As such, when switching on an enum we can guarantee that every possible option is accounted for.

One issue I see occasionally is abusing the default case. Consider the following example:

enum Style {
case small
case big
}

func size(for style: Style) -> CGFloat {
switch style {
case .small:
8
default:
16
}
}

On the surface this seems perfectly reasonable, but imagine a new developer is tasked with adding a third style - medium. Unless that dev already knows about the size(for:) function, the app will start behaving incorrectly… silently…

enum Style {
case small
case medium
case big
}

func size(for style: Style) -> CGFloat {
switch style {
case .small:
8
default: // Uh oh!
16
}
}

The solution to this particular example is simple. If we explicitly list all the enum cases, when medium is added, the compiler will prompt let us know that the switch must be exhaustive and that we’ve not handled medium.

enum Style {
case small
case medium
case big
}

func size(for style: Style) -> CGFloat {
switch style {
case .small:
8
case .medium:
12
case .big:
16
}
}

Conclusion

Obviously the example presented is contrived but the concept is worth applying whenever you are about to use a default case.

The power of enums is in their completeness, so don’t throw that away with a default case unless you’re sure that’s what you want!

And as a rule of thumb:

Never lay traps for future devs

--

--

Toby O'Connell

Swift / iOS developer - I write about things that I find interesting or innovative.