if let과 guard let으로 옵셔널 안전하게 다루기
옵셔널 값을 안전하게 꺼내는 if let과 guard let의 제어 흐름과 사용 기준을 비교합니다.

옵셔널을 꺼내는 두 문법은 결과만 보면 비슷하지만 이후 코드가 흐르는 방향은 정반대다. 조건 안에서 짧게 사용할지, 실패를 먼저 끝내고 정상 흐름을 이어갈지에 따라 선택이 달라진다.
if let
조건문 안의 옵셔널 값이 nil인지 체크하고, 각 경우에 대한 처리를 안전하게 수행한다. 보통 각 조건에 따른 처리를 위해 사용되지만, else문을 생략하고 사용할 수 있다. 옵셔널 바인딩 된 상수 if문 안에서만 사용할 수 있다.
struct UnwrapStudy: View {
@State var currentUserID: String? = "Snack"
@State var displayText: String? = nil
@State var isLoading: Bool = false
var body: some View {
VStack {
// displayText가 nil이 아닌 경우
if let text = displayText {
Text(text)
.font(.title)
}
if isLoading {
ProgressView()
}
}
.onAppear {
loadData()
}
}
func loadData() {
// currentUserID가 nil이 아닌 경우
if let userID = currentUserID {
isLoading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
displayText = "The username is \(userID)."
isLoading = false
}
// currentUserID가 nil인 경우
} else {
displayText = "There is no user data."
}
}
}
guard let
- 블록 내부에서만 사용되며, 옵셔널 값을 체크하여
nil인 경우에 대한 처리를guard절 안에서 바로 수행한다. return,break,continue,throw등의 제어문 전환 명령어를 필수로 입력한다.- 옵셔널 바인딩 된 상수를
else문을 제외한 블록 내에서 사용할 수 있다. - 예외사항 처리를 먼저 수행하여 코드의 안정성과 가독성이 향상된다.
struct UnwrapStudy: View {
@State var currentUserID: String? = "Snack"
@State var displayText: String? = nil
@State var isLoading: Bool = false
var body: some View {
VStack {
// displayText가 nil이 아닌 경우
if let text = displayText {
Text(text)
.font(.title)
}
if isLoading {
ProgressView()
}
}
.onAppear {
loadData()
}
}
func loadData() {
guard let userID = currentUserID else {
// currentUserID가 nil인 경우
displayText = "There is no user data."
return // 함수 종료
}
// currentUserID가 nil이 아닌 경우
isLoading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
displayText = "The username is \(userID)."
isLoading = false
}
}
}