
optional은 변수와 값 사이에 하나의 보호막이 더 있는 개념이라고 보면 된다. 값이 있을 수도 있고 없을 수 도 있는 어떠한 상자의 느낌이다. ! 혹은 ?로 정의할 수 있는데 둘 다 다른 타입과 달리 nil값을 할당할 수 있다. !로 정의하면 변수처럼 연산이 가능하고 ?로 정의하면 변수처럼 연산을 할 수 없다. optional에서 진짜 값을 추출하기 위해서는 optional binding 혹은 force unwrapping을 사용하는데, optional binding은 값이 있는 경우에만 해당값을 임시 변수에 할당하여 블록 내에서 사용할 수 있게 해주는 것이고, force unwrapping은 !를 이용하여 값을 강제로 추출하는 방법이다.
값이 있을 수도 있고 없을 수도 있다.
optional이 아닌 상수에 nil값을 할당하려고 하면 에러가 난다.
let optionalConstant: Int? = nil
let someConstant: Int = nil // 불가
nil의 가능성을 문서화하지 않아도 코드만으로 충분히 표현하가능하게 해준다.
- 문서나 주석을 작성하는 시간을 절약할 수 있다.
전달받은 값이 옵셔널이 아니라면 nil체크를 하지 않더라도 안심하고 사용하게 해준다.
- 효율적이고 예외상황을 최소화하는 안전한 코딩을 할 수 있다.
func someFunction(someOptionalParam: Int?){ }
someFunction(someOptionalParam: nil)
func someFunction(someParam: Int){ }
someFunction(someParam: nil) // 불가
optional은 enum으로 이루어져 있다.
enum Optional<Wrapped> : ExpressibleByNilLiteral{
case none
case some(Wrapped)
}
let optionalValue: Optional<Int> = nil
let optionalValue: Int? = nil
암시적 추출 옵셔널
var optionalValue: Int! = 100
switch optionalValue {
case.none:
print("This Optional variable is nil")
case.some(let value):
print(Vaule is \(value))
}
//기존 변수처럼 사용가능하다
optionalValue = optionalValue +1
//nil 할당 가능
optionalValue = nil
//nil이 할당되어 있으므로 잘못된 접근으로 인한 런타임 오류 발생
optionalValue = optionalValue +1
var optionalValue : Int? = 100
switch optionalValue {
case .none:
print("This Optional variable is nil")
case .some:
print("Value is\(value)")
}
// nil할당 가능
optionalValue = nil
//기존 변수처럼 사용불가 - 옵셔널과 일반 값은 다른 타입이므로 연산 불가
optionalValue = optionalValue +1

func printName(_ name: String){
print(name)
}
var myName: String? = nil
printName(myName) // 전달되는 값의 타입이 다르기 때문에 컴파일 오류 발생
nil체크 후 안전한 값 추출
func printName(_name: String){
print(name)
}
var myName: String! = nil
if let name: String = myName{
printName(name)
}else{
print("myName == nil")
}
//name 상수는 if-let 구문 내에서만 사용가능하다.
// 상수 사용 범위를 벗어났기 때문에 컴파일 오류가 발생한다.
printName(name)
여러 옵셔널 변수를 한 번에 바인딩 할 수 있다
var myName : String? = "dora"
var yourName : String? = nil
if let name = myName, let friend = yourName {
print"\(name) and \(friend)"
}
//모두 값이 들어있어야 실행된다.
//yourName이 nil이기 때문에 실행되지 않는다
yourName = "hana"
//값을 넣은 후
if let name = myName, let friend = yourName{
print("\(name) and \(friend)")
}
// 추출 가능!
func printName(_name: String){
print(name)
}
var myName: String? = "dora"
//강제로 추출
printName(myName!)
myName = nil
//nil을 할당
print(myName!)
// 강제 추출 시 값이 없으므로 런타임 오류 발생
var yourName : String! = nil
printName(yourName)
//nil값이 전달되기 때문에 런타임 오류 발생
추천되는 방법은 아니고 안전하게 추출하기 위해서는 옵셔널 바인딩이 필요하다.