Optional
값을 반환할 때 오류가 발생할 가능성이 있는 값은 옵셔널 타입이라는 객체로 감싸서 반환한다.
어떤 값이 있을 수도 있고 없을 수도 있는 값에 쓰이는 타입임. 예를 들어서
Int("100")은 Optional(100)이라는 값을 리턴한다.
근데 Int("Hi")는 정수 값을 반환할 수 없기 때문에 아무 것도 반환할 수 없다는 의미의
nil을 반환하게 됨.
이렇게 값이 들어갈 수도 있고 들어가지 않을 수도 있는데 이런 경우에 일반 변수가 아니고 옵셔널 타입의 변수로
선언하자는 것이다.
따라서 옵셔널 타입은 변수 또는 상수에 아무런 값이 할당되지 않은 상황을 안전하게 처리하기 위한 방법을 제공한다.
그래서 옵셔널 타입으로 선언을 어떻게 하느냐. 간단하게 타입 선언부 뒤에 ?를 붙여주면 된다.
var index: Int? 이렇게 선언하면 index 변수는 Int형일 수도 있고 nil일 수도 있다는 것임.
강제 언래핑(forced unwrapping)
var x: Int?
x = 10
print(x)
print(x!)
이렇게 옵셔널 정수형 변수를 선언해주고 10으로 초기화 했음. 그리고 변수 x를 그냥 출력하게 되면 그냥 10이 출력되는 게 아니고Optional()로 감싸진 Optional(10)이라는 값이 출력된다.
이런 것들을 감싸졌다, wrapping(래핑)되었다라고 한다.
근데 그냥 10은 가지고 놀 수 있는데 이렇게 감싸진 값들은 가지고 놀 수가 없어.
연산도 못하고 그래서 10이라는 값을 쓰려면 벗겨줘야 하는데 이 과정을 unwrapping(언래핑)한다고 얘기한다.
두 번째 프린트문에서는 x!라고 느낌표가 붙은 것을 볼 수 있는데 이게 언래핑을 하는 여러가지 방법 중에
강제 언래핑 하는 방법이다.
그래서 x! 하게 되면 forced unwrapping 돼서 10이라는 값이 나오게 됨.
그래서 옵셔널 변수는 항상 nil인지 아닌지 아래처럼 체크를 해봐야함!
var x: Int?
var y: Int?
x = 10
if x != nil {
print(x!)
} else {
print("nil")
}
if y != nil {
print(y!)
} else {
print("nil")
}
별로 어렵지 않은 조건문이죠. x랑 y가 nil이 아니면(값이 들어있으면) 느낌표로 강제 언래핑해서 값을 출력하고 아니면 nil을 출력하는것.
근데 왜 이렇게 체크해야해요? 값이 없는 게 nil이라고 했는데 nil일 때 언래핑 하면 그냥 nil이 나오는 거 아닌가요.
No!
값이 아무것도 없는데 !로 강제 언래핑하면 앱이 크래쉬나서 다운됨!!
nil은 값이 아니라 아무것도 없는 상태임. nil이 나오려면 "nil"이라는 값이 있다는 거겠죠?
그렇기 때문에 반드시 nil이 아닐 때만 언래핑 해줘야한다.
이렇기 때문에 사실 강제 언래핑은 위험한 일이다. 이름부터 좀 위험해보이지 않았니? 강제라니..
Optional Binding
그래서 언래핑하는 또 다른 방법으로 옵셔널 바인딩이라는 것을 사용할게.
이건 옵셔널에 할당된 값을 임시 변수/상수에 할당하는거임. 이게 뭔소리냐면
if let xValue = x {
print("xValue = \(xValue)")
}
이렇게 쓰는거임. 처음 봤을 때 어떻게 보이니? 어 조건문인데 xValue에 x를 할당하고 참이면 프린트문 출력? 이게 먼솔
이게 굉장히 웃겨요. 옵셔널 변수 x가 값이 있으면 언래핑해서 일반 상수 xValue에 대입하고 if문을 실행합니다.
x가 값이 없으면 조건이 거짓이 돼서 if문 실행하지 않음. 이렇게 두가지 의미를 함축하고 있는 문장이에요. 재밌죠.
중요한 건 언래핑을 해준다는 거예요.
이렇게 if let이나 if var를 쓰는 것을 옵셔널 바인딩한다라고 얘기를 합니다.
값이 없으면(nil 이면) 언래핑도 안 하고 조건문도 실행을 안 하니 안전하죠잉.
한 번 더 해보면
var x: Int?
var y: Int?
x = 10
if let xValue = x {
print("xValue = \(xValue)")
}
if let yy = y {
print(yy)
} else {
print("nil")
}
어떠신가요? 이제 앱이 크래쉬 날 일이 없죠.
어려개의 옵셔널 변수가 있을 때는
변수 하나하나 마다 if let을 쓰지 않아도 됨.
var fruit1: String?
var fruit2: String?
fruit1 = "apple"
fruit2 = "orange"
if let realFruit1 = fruit1, let realFruit2 = fruit2 {
print(realFruit1, realFruit2)
} else {
print("nil")
}
이렇게 하나의 if에 let, let 이런 식으로 한 번에 처리할 수 있따는 사실.
단, 모든 애들이 다 nil이 아니어야지 if문이 실행된다.
🚦정리
왜 옵셔널을 쓰냐?
nil값을 가질 수 있음. nil은 값이 없는 상태. nil은 옵셔널이 아닌 일반 변수/상수에 할당할 수 없음.
(옵셔널 변수는 초기값을 안 줘도 자동으로 nil이 들어감)
상수나 변수가 값이 없는 상태가 존재한다면 옵셔널 타입으로 선언해야한다!
'Swift' 카테고리의 다른 글
형변환 (0) | 2025.03.08 |
---|---|
옵셔널 (2) (0) | 2025.03.07 |
[03] 1주차: 버튼과 텍스트를 사용하여 UI 실습 (1) | 2025.03.05 |
[02] 1주차: 간단한 화면 구성 (0) | 2025.03.05 |
[01] 1주차: Swift 기초 (0) | 2025.02.27 |