이번에는 Swift에서만 사용되는 새로운 개념인 옵셔널에 대해 알아보도록 하겠습니다.
옵셔널(Optional)은 데이터가 할당되지 않을 수도 있도록 하는 타입을 말합니다.
아무런 데이터도 할당되어 있지 않다는 것은 nil로 표현되며, 할당을 하지 않은 옵셔널은 저절로 nil 값을 가지게 됩니다.
래핑(wrapping)은 옵셔널에 값을 할당하는 것을 뜻합니다.
옵셔널은 데이터 타입 선언 끝에 물음표(?)를 붙여서 표기하며, 해당 데이터 타입과 nil 값을 표현할 수 있는 형태가 됩니다.
Swift에서는 옵셔널이 아닌 일반적인 변수나 상수에는 nil을 할당할 수 없으며, 반드시 데이터가 있어야 합니다.
//옵셔널 선언
var number: Int?
var name: String?
//옵셔널 래핑
number = 123
강제 언래핑(unwrapping)
강제 언래핑은 옵셔널 이름 끝에 느낌표(!)를 붙여 옵셔널에 래핑된 값을 강제로 뽑아내는 것을 말합니다.
주의 : nil이 할당되어 있으면 런타임 오류가 발생하므로 가급적이면 사용하지 않는 것이 좋습니다.
var number: Int? = 123
var name: String? = "홍길동"
print("\(number!) \(name!)") //123 홍길동 출력
number = nil
//print("\(number!)") 과 같이 강제 언래핑 시 오류 발생
옵셔널 바인딩(if let)
옵셔널 바인딩은 옵셔널에 할당된 값을 임시 변수나 상수에 할당하는 것을 말합니다.
if let 구문으로 지정된 옵셔널에 값이 있는지 확인하고, 값이 있으면 임시 변수나 상수에 해당 값을 할당하고, nil이면 else 부분을 실행합니다.
if let 구문에서 임시 변수나 상수는 옵셔널과 같은 이름으로도 사용할 수 있으며, 이때는 같은 이름의 임시 변수나 상수에 옵셔널 값이 할당됩니다.
var number: Int?
//옵셔널 number에 값이 있으면 임시 상수 num에 옵셔널 값 할당
if let num = number {
print("\(num)")
}else{
print("변수에 값이 할당되어 있지 않음")
} // 변수에 값이 할당되어 있지 않음 출력
number = 123
if let num = number {
print("\(num)")
}else{
print("변수에 값이 할당되어 있지 않음")
} // 123 출력
옵셔널 이름만 써도 if let 구문 안에서는 같은 이름의 임시 상수로 적용됩니다.
var number: Int? = 123
//옵셔널 number에 값이 있으면 같은 이름의 임시 상수에 옵셔널 값 할당
if let number {
print("\(number)")
}else{
print("변수에 값이 할당되어 있지 않음")
} // 123 출력
else 부분에 중점이라면 조건문 중 guard let 구문을 사용하여 언래핑이 가능합니다.
옵셔널 언래핑에 실패하면 guard 구문을 통과하지 않고 끝납니다.
var number: Int?
//옵셔널 number에 값이 있으면 임시 상수 num에 옵셔널 값 할당
func printNum(number: Int?){
guard let number else{
print("변수에 값이 할당되어 있지 않음")
return
}
print("\(number)")
}
printNum(number: number)// 변수에 값이 할당되어 있지 않음 출력
number = 123
printNum(number: number) // 123 출력
좀 더 간단히 언래핑을 하려면아래와 같이 let (상수명):(타입) = (옵셔널 이름) ?? (nil 시 표기할 대체값) 형태로 표기할 수 있으며, 이렇게 표기하면 언래핑이 불가능할 때 대체값을 반환합니다.
var number: Int? = 123
let newNumber:Int = number ?? 0
print("\(newNumber)") // 123 출력
여러 개의 옵셔널을 쉼표(,)로 구분하여 언래핑도 가능합니다.
var busNumber: Int?
var busLocation: String?
var busInterval: Int?
if let busNumber, let busLocation, let busInterval{
print("""
버스 번호: \(busNumber)
버스 운행 구간: \(busLocation)
운행 간격: \(busInterval) 분
""")
}else{
print("버스 정보가 올바르지 않습니다")
} //버스 정보가 올바르지 않습니다 출력
busNumber = 1234
busLocation = "을지로~원흥역"
busInterval = 10
if let busNumber, let busLocation, let busInterval{
print("""
버스 번호: \(busNumber)
버스 운행 구간: \(busLocation)
운행 간격: \(busInterval)분
""")
}else{
print("버스 정보가 올바르지 않습니다")
}
/*
버스 번호: 1234
버스 운행 구간: 을지로~원흥역
운행 간격: 10분
*/
아래와 같이 여러 개의 옵셔널과 조건문을 같이 적용할 수도 있습니다.
var busNumber: Int? = 1234
var busLocation: String? = "을지로~원흥역"
var busInterval: Int? = 10
var isRunning: Bool = false // 운행중 여부
if let busNumber, let busLocation, let busInterval, isRunning{
print("""
버스 번호: \(busNumber)
버스 운행 구간: \(busLocation)
운행 간격: \(busInterval) 분
""")
}else{
print("버스 정보가 올바르지 않거나 운행이 종료되었습니다")
} //isRunning이 false이므로 버스 정보가 올바르지 않거나 운행이 종료되었습니다 출력
대체값 반환 응용 - 문자열을 숫자형 데이터로 변환
문자열 타입 데이터를 정수형이나 부동소수점 형식으로 변환할 때 숫자가 아닌 데이터를 강제로 변환하면 발생하는 오류를 옵셔널 언래핑을 이용하여 해결할 수 있습니다.
타입 변환 코드 뒤에 ?? (대체값) 을 붙여서 사용하며, 숫자가 아닌 데이터를 받으면 대체값이 반환됩니다.
문자열에서 정수형 데이터로 바꿀 때 소수점이 있으면 변환이 불가능하며, 대체값이 반환됩니다.
var myString: String = "안녕하세요"
var myInt: Int = Int(myString) ?? 0
print("myInt: \(myInt)")
var myDouble: Double = Double(myString) ?? 0.0
print("myDouble: \(myDouble)")
myString = "30"
myInt = Int(myString) ?? 0
print("myInt: \(myInt)") // myInt: 30
myDouble = Double(myString) ?? 0.0
print("myDouble: \(myDouble)") // myDouble: 30.0
myString = "34.56"
myInt = Int(myString) ?? 0
print("myInt: \(myInt)") // myInt: 0
myDouble = Double(myString) ?? 0.0
print("myDouble: \(myDouble)") // myDouble: 34.56
여기까지 Swift에서의 옵셔널에 관해 알아보았습니다.
다음 글에서는 함수에 관해 알아보도록 하겠습니다.
감사합니다.
'iOS 애플리케이션 개발 > Swift 학습노트' 카테고리의 다른 글
4. 함수 (0) | 2024.03.08 |
---|---|
2. 제어 구문과 3항식 (0) | 2024.01.19 |
1. Swift 언어 기초 - 변수와 상수, 데이터 타입 (0) | 2024.01.19 |
프롤로그 - 블로그를 다시 시작하며 (0) | 2024.01.19 |