iOS 개발자가 많이 하는 실수 - switch-case에서 default를 사용하고 enum 케이스 추가 시 실수
Swift의 switch 문은 패턴 매칭이 정확하고 안전하게 동작하도록 설계된 문법입니다.
특히 enum과 함께 사용할 때는 강력한 타입 안정성을 보장합니다.
하지만 개발자가 가장 많이 저지르는 실수 중 하나가 바로:
switch 문에 무지성 default를 넣어 enum 확장이 감지되지 않는 문제
이 문제는 컴파일 오류가 발생하지 않는 조용한 버그를 만들어내기 때문에
실무에서 매우 위험한 실수로 평가됩니다.
1. 문제 패턴
대표적인 잘못된 코드:
enum Status {
case ready
case running
case finished
}
func handle(_ status: Status) {
switch status {
case .ready:
print("Ready")
case .running:
print("Running")
default:
print("Other") // ❌ 여기가 문제
}
}
이 코드의 문제는 다음과 같습니다:
- 지금은 잘 동작해 보임
- 이후 enum에 새로운 케이스가 추가되면…
case paused
- 컴파일러는 경고도 에러도 발생시키지 않음
- 새로운 케이스가 default에 빨려 들어가서 버그 발생
- 개발자는 “왜 새로운 기능이 동작하지 않지?” 하며 디버깅 시작
2. default가 왜 위험한가?
2-1. enum 확장 시 버그를 숨긴다
enum ConnectionState {
case connected
case disconnected
case reconnecting
}
여기에 새로운 케이스가 추가돼도:
case failed
기존 switch는 그대로 컴파일됨:
switch state {
case .connected:
...
default:
... // 신규 케이스가 여기로 들어와서 버그 발생
}
Swift의 강점을 스스로 제거해 버린 것이다.
2-2. 코드 읽기가 어렵다
default는 무슨 상황을 처리하는지 알기 어렵다.
예:
default:
showError() // ❓ 이게 어떤 케이스?
2-3. 타입 안정성을 잃어버린다
Swift의 enum + switch 조합은 원래 다음을 보장한다:
- 모든 케이스 처리 강제
- 확장 시 컴파일 타임 오류 발생
- 의도하지 않은 분기 방지
하지만 default를 넣는 순간 이 장점은 사라진다.
3. 올바른 switch-case 작성법
3-1. default를 사용하지 않고 모든 케이스를 명시
switch status {
case .ready:
...
case .running:
...
case .finished:
...
}
이렇게 쓰면 새로운 케이스가 추가될 때 반드시 컴파일 오류가 발생한다.
예:
enum Status {
case ready
case running
case finished
case paused // 신규 추가
}
그러면 기존 switch에서:
Switch must be exhaustive
Do you want to add missing case?
→ 바로 문제를 발견할 수 있음
3-2. 정말 default가 필요한 경우 (매우 드물다)
default는 다음 상황에서만 사용해야 한다.
✔ 1) enum이 아닌 타입에서 패턴 매칭할 때
예: 숫자 범위, 문자열 패턴 등
switch value {
case 0:
...
case 1...10:
...
default:
...
}
✔ 2) enum에 관련 없는 fallback을 의도적으로 표현해야 할 때
예:
switch httpCode {
case 200:
showOK()
case 400:
showBadRequest()
default:
showGenericError()
}
이 경우 default는 범위를 나타내므로 사용해도 괜찮다.
✔ 3) @unknown default (강력 추천)
Swift는 Apple Framework 등 외부에서 제공하는 enum 확장에 대비하기 위해
@unknown default를 지원한다.
예:
switch traitCollection.userInterfaceStyle {
case .light:
...
case .dark:
...
@unknown default:
...
}
장점:
- Apple이 enum을 확장하면 컴파일러가 경고를 띄워줌
- default가 “정말 fallback”이라는 의도가 명확함
4. 실무 스타일 예시
나쁜 예
switch state {
case .loading:
showLoading()
default:
showError()
}
새 케이스 .success, .failed가 생겨도 무조건 showError()가 실행됨 → 버그
좋은 예
switch state {
case .loading:
showLoading()
case .success:
showSuccess()
case .failed:
showError()
}
케이스 추가 시 컴파일 에러로 문제를 바로 발견 가능.
외부 enum을 다룰 때 좋은 예
switch style {
case .light:
configureLight()
case .dark:
configureDark()
@unknown default:
configureDefault()
}
5. 마무리 정리
- default는 enum 확장 시 bug를 숨기는 가장 위험한 요소
- Swift switch의 장점(타입 안정성, exhaustive 체크)이 사라진다
- 특히 실무에서 enum 로직은 자주 변경·추가되므로 default 남발은 금물
- 기본 원칙은:
enum + switch 조합에서는 default를 쓰지 말아라.
꼭 필요하다면 @unknown default만 사용하라.

