Optinal의 필요성
코딩을 하면서 어떠한 변수에 값이 있을 수도 없을 수도 있는 경우를 위해서 입니다.
예제를 하나 살펴봅시다.
var x: Int
x = nill // 오류
오류가 나는 원인은 nil은 Int형 타입에 할당 될 수 없기 때문입니다.
Int타입에 메모리 공간에 Int타입이 아닌 것을 넣어서 메모리공간이 초기화 될 수 없는 것입니다.
코딩을 하다보면 어떤 변수에 값이 없을 수도 있겠죠?
변수안에 값이 있다는 것을 확실히 보장 할 수 없으면 Optional을 씁니다.
var x: Int?
x = nill // 정상작동
//혹은
var x: Int!
x = nill // 정상작동
optional 기호 ? 또는 !를 붙여서 변수에 값이 있을 수도, 없을 수도 있다는 것을 명시해줬습니다.
Swift가 기본적으로 non-optional을 지원합니다.
swift에서는 기본적으로 변수를 선언할 때 non-optional인 값을 주어야 합니다.
즉 어떠한 '값'을 변수에게 주어야 합니다.
쉽게 말해서 그림의 박스와 같이 optional을 값들을 보호해주는 보호막이라고 생각하시면 됩니다. 또한 optional 타입은 기본적으로 nill이 들어있습니다.
하나의 예를 더 살펴볼게요.
var someValue :Int? = 30
var value : Int = someValue // 오류
value 변수는 Int형 데이터만 가질수 있습니다.
someValue Optional타입을 가지는(nil이 들어 갈 수도 있는) 변수입니다.
value에 someValue를 넣어주었으니 당연히 Value는 someValue를 받지 못합니다.
명심하세요! Int? 와 Int는 다른 타입입니다.
Optinal binding
위의 그림의 저 박스에 노크를 해서 값이 있으면 값을 꺼내오고, 값이 없으면 값을 꺼내오지 않고 지나치게 됩니다.
var myName: String? = nil
func printName(_ name: String) { // name:string 타입
print(name)
}
if let name: String = myName {
printName(name)
} else {
print("myName == nil")
}
Unwrapping(강제추출)
저 박스에서 망치로 박스를 깨서 강제로 값을 가져오는 것입니다.
unwrapping같은 경우에는 optional binding과 다르게 값이 있는지 없는지 확인하지 않고 강제로 값을 추출하는 방식입니다.
만약 값이 없을경우(nil) 런타임 오류가 발생하기 때문에 추천되지 않습니다.
var myName: String? = yagom
func printName(_ name: String) { // name:string 타입
print(name)
}
// 강제추출
printName(myName!) // yagom
myName = nil
// 강제추출시 값이 없으므로 런타임 오류 발생
//print(myName!)
// nil 값이 전달되기 때문에 런타임 오류발생
var youName: String! = nil
printName(youName)