DAY 05
옵셔널(optional)
Int형 vs Optional Int형
Int
- Int형 값을 저장
var x : Int = 10
값 10이 변수 x에 저장됨
Int?, Int!
- Int형 값을 저장 or 값이 없음(nil)
var y : Int? = 10
var z : Int!
값 Optional(10)이 변수 y에 저장됨
옵셔널 타입(Optional Type)
값을 반환할 때 오류가 발생할 가능성이 있는 값은 옵셔널 타입이라는 객체로 감싸서 반환함
Int("Hi")
와 같은 경우 정수 값을 반환할 수 없으므로 nil을 반환해야 하는데,
Swift 기본 자료형에서는 nil값을 저장할 수 없으므로 Optional Type으로 선언해야 함
- 옵셔널 타입은 변수 또는 상수에 아무런 값이 할당되지 않는 상황을 안전하게 처리하기 위한 방법 제공
- 옵셔널 타입 변수를 선언하기 위해서는 타입 선언부 뒤에 ? 문자를 씀
옵셔널 타입 강제 언래핑(forced unwrapping)
옵셔널 변수에 값이 있으면 옵셔널로 래핑되었다(wrapped)라고 함
옵셔널에 래핑된 값은 강제 언래핑(forced unwrapping)으로 풀어줌
var x: Int?
var y: Int = 0
x = 10
print(x)
print(x!)
print(y)
output
Optional(10)
10
0
print(x)
에서 x는 : Int?
옵셔널 변수로 선언되었기 때문에 출력결과 Optional(10)
으로 출력된다
print(x!)
에서는 x가 x!
키워드로 강제 언래핑되어 출력되었기 때문에 Int형 10이 출력됨
만약 x = x+2 와 같은 연산을 시도한다면, 옵셔널 타입과 Int타입이 계산되지 않기 때문에 오류가 발생함
var x: Int?
x = 10
if x != nil {
print(x!)
} else {
print("nil")
}
출력결과 x가 강제 언래핑되어 x!
인 10이 출력된다
강제 언래핑(forced unwrapping) - optional binding
강제 언래핑하는 또 다른 방법으로, 옵셔널 바인딩(optional binding)을 이용하여 옵셔널에 할당된 값을 임시 변수 또는 상수에 할당
if let constantName = optionalName {
// if not nil - run this
}
if var variableName = optionalName {
// if not nil - run this
}
다음과 같은 형식으로 표현하는 것이 일반적이며, optionalName
에 담긴 값을 임의의 상수 혹은 변수로 optional binding을 통해 값을 언래핑시킬 수 있음
var x: Int?
x = 10
if let xx = x {
print(xx)
} else {
print("nil")
}
var x1: Int?
if let xx = x1 {
print(xx)
} else {
print("nil")
}
output
10
nil
optional Int
인 x의 값을 상수 xx로 optional binding시켜 Int
로 unwrapping하고 값을 출력
x1
은 nil이기 때문에, "nil"을 출력함
여러 옵셔널 변수를 한번에 언래핑하는 방법
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
if let firstPet = pet1, let secondPet = pet2 {
print(firstPet, secondPet)
} else {
print("nil")
}
다음과 같이 if
문의 comma(,)를 이용하여 여러 옵셔널 변수를 한번에 언래핑할 수 있다
두 가지 옵셔널 타입
옵셔널이 항상 유효한 값을 가질 경우 옵셔널이 암묵적인 언래핑(implicitly unwrapped)이 되도록 선언할 수 있다
이러한 방법으로 옵셔널이 선언된다면 강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근할 수 있음
암묵적인 언래핑으로 옵셔널을 선언하기 위해서는 선언부에 물음표(?) 대신 느낌표(!)를 사용
var x: Int?
var y: Int!
스위프트 공식 문서 참조
Implicitly Unwrapped Optional
일반 옵셔널 값으로 사용하려고 하지만, optional로 사용할 수 없는 경우 swift는 값을 강제로 푼다
Optional로 사용되지 않으면 강제로 unwrap한다
let a: Int! = 1
let b: Int = a
let c: Int = a!
let d = a
let e = a + 1
print(a, b, c, d, e)
print(type(of:a), type(of:b), type(of:c), type(of:d), type(of:e))
output
Optional(1) 1 1 Optional(1) 2
Optional<Int> Int Int Optional<Int> Int
a
는 implicitly unwrapped으로 옵셔널이 선언되어 타입은 Optional<Int>
이지만, b
에서 Optional로 사용될 수 없으므로 강제로 unrwapping 하는것을 볼 수 있다
c
처럼 굳이 a
를 강제 언래핑 하지 않아도 사용할 수 없는 경우 강제로 unwrapping 해준다
하지만 d
처럼 type을 명시하지 않은 경우는 그대로 Optional 타입으로 선언된다
Any와 AnyObject
AnyObject(protocol)
어떠한 클래스의 객체도 저장할 수 있음
클래스만 허용하며 구조체나 열거형은 허용하지 않음
Any
어떠한 타입도 표현할 수 있다
클래스, 구조체, 열거형, 함수타입도 가능
var x: Any = "Hi"
print(x, type(of:x))
x = 10
print(x, type(of:x))
x = 3.5
print(x, type(of:x))
output
String
Int
Double
다음과 같이 값이 초기화될 때 마다 타입이 변한다
댓글