Swift는 타입 안전성과 런타임 오류를 최소화하기 위한 여러 기능을 언어 차원에서 제공합니다.
그 중에서도 대표적인 것이 옵셔널(Optional), guard문, 그리고 defer문입니다.
이러한 문법들은 코드의 안정성과 예측 가능성을 높이며, 오류 발생 가능성을 줄이는 데 중요한 역할을 합니다.
이번 글에서는 Swift에서 안전하게 코드를 작성하기 위해 꼭 알아야 할 문법들을 예제와 함께 살펴보겠습니다.
1. 옵셔널(Optional)
옵셔널은 값이 있을 수도 있고 없을 수도 있는 경우를 표현하기 위해 사용되는 타입입니다.
Swift에서는 ?
기호를 사용하여 옵셔널을 정의합니다.
var name: String? = "지민"
print(name) // Optional("지민")
옵셔널 값을 안전하게 사용하려면 언래핑(unwrapping)이 필요합니다.
1-1. 옵셔널 바인딩 (Optional Binding)
가장 일반적인 방식은 if let
이나 guard let
을 사용하는 것입니다.
if let actualName = name {
print("이름은 \(actualName)입니다.")
} else {
print("이름이 없습니다.")
}
1-2. 옵셔널 체이닝 (Optional Chaining)
옵셔널 속성이나 메서드에 연쇄적으로 접근할 수 있습니다.
let text: String? = "Swift"
let count = text?.count
print(count) // Optional(5)
1-3. nil 병합 연산자 (Nil-Coalescing Operator)
옵셔널이 nil인 경우 기본값을 설정할 수 있습니다.
let nickname: String? = nil
let displayName = nickname ?? "사용자"
print(displayName) // 사용자
2. guard문
guard
는 조기 탈출을 통해 조건이 충족되지 않으면 빠르게 함수나 블록에서 빠져나가게 도와줍니다.
옵셔널 바인딩과 함께 자주 사용됩니다.
func greet(_ name: String?) {
guard let unwrappedName = name else {
print("이름이 없습니다.")
return
}
print("안녕하세요, \(unwrappedName)님!")
}
guard
는 조건이 false
일 경우에만 실행되며, 함수의 흐름을 명확히 해주는 데 유리합니다.
3. defer문
defer
는 현재 범위에서 빠져나가기 직전에 반드시 실행되어야 할 코드를 등록할 수 있는 문법입니다.
주로 리소스 해제, 파일 닫기, 상태 복원 등의 작업에 활용됩니다.
func processFile() {
print("파일 열기")
defer {
print("파일 닫기")
}
print("파일 처리 중")
}
processFile()
// 출력:
// 파일 열기
// 파일 처리 중
// 파일 닫기
defer
는 여러 개 작성할 수 있으며, 작성된 역순으로 실행됩니다.
마무리
Swift는 오류 가능성을 줄이고, 코드 흐름을 명확하게 하기 위해 다양한 안전한 문법을 제공합니다.
옵셔널은 값의 존재 여부를 명확히 표현하고, guard
는 방어적 코드 작성에 탁월하며, defer
는 종료 시점에서 반드시 수행할 작업을 책임집니다.
이러한 문법들을 이해하고 적절히 활용하면 더 예측 가능하고 안전한 Swift 코드를 작성할 수 있습니다.