값이 있을 수도 있고, 없을 수도 있는 변수
let variableOne: Int = nil // 불가능
let variableTwo: Int! = nil // 가능
let variableThree: Int? = nil // 가능
func someFunction(someOptionalParam: Int?) { }
func someFunction(someParam: Int) { }
someFunction(someOptionalParam: nil) // 가능
someFunction(someParam: nil) // 불가능
옵셔널은 enum과 general의 합작품! 옵셔널에 값이 있으면 some의 연관 값인 Wrapped에 값이 할당된다. 즉, 값
이 옵셔널
이라는 방패막에 보호되어 있는 형태다.
enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none // 옵셔널에 값이 없을 때
case some(Wrapped) // 옵셔널에 값이 있을 때
}
let optionalValue: Optional<Int> = nil
let optionalValue: Int? = nil
전자처럼 선언하는 것이 정석이지만 후자처럼 간단히 선언해줄 수 있다. 물음표는 타입과 반드시 붙여서 작성해야 한다.
옵셔널은 물음표(?)와 느낌표(!)로 표현할 수 있다.
var optionalValue: Int! = 100
var optionalValue: Int? = 100
옵셔널 타입 자체는 열거형이기 때문에 이런 식으로 switch문을 통해 값이 있고 없음을 확인할 수 있다.
switch optionalValue {
case .none: // 옵셔널에 값이 없으면
print(“This Optional variable is nil”)
case .some(let value): // 옵셔널에 값이 있으면
print(“Value is \(value)”)
}
옵셔널 타입은 Int 등 일반 타입과는 다른 타입으로 취급되므로, 옵셔널 타입-일반 타입 간의 연산이나 값 교환이 불가능
var optionalValue: Int? = 100
optionalValue = optionalValue + 1 // 기존 변수처럼 사용 불가
optionalValue = nil // nil 할당 가능
var optionalValue: Int! = 100
optionalValue = optionalValue + 1 // 기존 변수처럼 사용 가능
optionalValue = nil // nil 할당 가능
optionalValue = optionalValue + 1 // 옵셔널에 nil이 할당되어 있을 때 접근 시도 -> 런타임 오류
nil 체크를 함과 동시에 안전하게 값을 꺼내오는 방식
if-let 구문으로 달성!
var myName: String? = nil
if let name: String = myName { // name은 if-let 구문 안에서만 사용 가능
print(name)
} else {
print(“myName == nil”)
}
한 번에 하나씩만 바인딩할 수 있는가? -> No
쉼표를 사용해 여러 옵셔널 변수들을 한꺼번에 바인딩할 수 있다. if-let 구문에 할당된 모든 옵셔널 변수들에 값이 있어야 해당 구문이 실행된다.
var myName: String? = "yagom"
var yourName: String? = nil
if let name = myName, let friend = yourName {
print("실행 X \(name) and \(friend)")
} // yourName이 nil이므로 실행 X 두 변수에 모두 값이 들어있어야 실행
yourName = "hana"
if let name = myName, let friend = yourName {
print("\(name) and \(friend)")
} // yagom and hana
옵셔널의 값을 강제로 추출하는 방식
보다 안전하게 옵셔널을 사용하기 위해서는 강제 추출보다는 옵셔널 바인딩 사용하기!
func printName(name: String) {
print(name)
}
var myName: String? = "yagom"
printName(name: myName!) // 강제추출
myName = nil
print(myName!) // 강제추출..했으나 값이 없으므로 런타임 오류
일반 타입 변수에는 nil을 할당할 수 없다.
optionalA는 일반 옵셔널 변수이므로 일반 타입 변수와의 연산이 불가능하다. optionalB는 암시적 추출 옵셔널 변수이므로 일반 타입 변수와의 연산이 가능하지만, optionalB에 현재 nil값이 할당되어 있으므로 에러가 발생한다.
if-let 구문 사용
야곰의 스위프트 기본 문법 강좌를 수강하며 작성한 내용입니다.