
옵셔널이 뭔데?
옵셔널은 두가지 가능성이 존재한다.
예를 들어서
문자열 "123"은 Int형으로 바꿀 수 있다. -> 123
하지만 "hello world"는 Int형으로 바꿀 수 없다. -> x
let number = "123"
let convertedNumber = Int(number)
// convertedNumber의 타입은 '옵셔널 Int'
위의 코드에서 "123"은 Int형으로 바꿀 수 있는 문자열이기 때문에 잘 변환되지만 혹시라도 "helloworld" 같이 Int형으로 변환할 수 없는 문자열이 올 경우 초기화가 실패할 수 있다.
이러한 실패의 가능성을 방지하기 위해 Int 가 아닌 옵셔널 Int 를 반환한다.
즉, 옵셔널은 '값이 없을 수도 있는 가능성을 방지'하기 위한 타입인 것이다. 🤲🏻
nil
그렇다면 옵셔널 타입의 변수에 값이 없다면 어떻게 나타낼 수 있을까?
1) 옵셔널 변수에 특수한 값 nil을 지정하여 값이 없는 상태로 나타낼 수 있다.
2) 만약 기본값 없이 옵셔널 변수를 정의한다면 이 변수는 자동적으로 nil로 설정된다.
var a: String?
// a는 nil로 설정
3) 또한 if 구문으로 옵셔널에 값이 있는지 확인할 수 있다.
if a != nil {
}
// 옵셔널에 값이 있다면 nil과 같지 않음
4) 옵셔널이 아닌 값에 nil을 할당하면 컴파일 오류가 발생한다.
5) 옵셔널 값에 접근할 때 코드에서 nil과 nil이 아닌 것에 대해 모두 처리해야한다.
< 값이 없을 때 수행할 수 있는 작업 >
- 값이 nil일 때 해당 값 동작 건너뛰기
- nil을 반환하거나 ?. 연산자를 사용해서 nil 값 전파
- ?? 연산자를 사용하여 대체값 제공
- ! 연산자를 사용해서 프로그램 멈추기
그렇다면 옵셔널에 값이 있는 경우엔?
옵셔널이 값을 포함하고 있는지 확인하고 값이 있는 경우 해당 값을 임시 상수 / 변수로 사용할 수 있는 것이 바로 '옵셔널 바인딩' 이다.
if, guard, while 구문에서 옵셔널에 값이 있는지 체크하고 추출함
if let actualNumber = Int(possibleNumber) {
print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
print("The string \"\(possibleNumber)\" could not be converted to an integer")
}
// Prints "The string "123" has an integer value of 123"
1) if let actualNumber = Int(possibleNumber)
반환된 옵셔널 Int에 값이 포함되어있으면, actualNumber라는 새로운 상수에 옵셔널에 포함된 값을 설정
2) else {
print("The string \"(possibleNumber)\" could not be converted to an integer")
}
반환된 옵셔널 Int에 값이 포함되어있지않으면, print문 출력
3) possibleNumber의 타입은 Int? (옵셔널 Int)
activeNumber의 타입은 Int
let myNumber = Int(possibleNumber)
// Here, myNumber is an optional integer
if let myNumber = myNumber {
// Here, myNumber is a non-optional integer
print("My number is \(myNumber)")
}
// Prints "My number is 123"
1) let myNumber = Int(possibleNumber)
myNumber가 값이 있는지 없는지 확인
2) if let myNumber = myNumber {
// Here, myNumber is a non-optional integer
print("My number is (myNumber)")
}
값이 있다면 해당 값이 새로운 myNumber라는 상수에 설정 (새로운 옵셔널이 아닌 상수를 참조)
if let myNumber = myNumber를 if let myNumber로 짧게 사용 가능
대체값 제공
nil-결합 연산자(??)를 사용하여 기본값을 제공한다.
왼쪽값 ?? 오른쪽값
강제 언래핑
프로그래머의 에러 또는 원치 않는 상태와 같은 실패를 표현하려면
옵셔널 이름 뒤에 느낌표 !를 추가하여 접근할 수 있다.
암시적으로 언래핑된 옵셔널
암시적으로 언래핑된 옵셔널...영어를 직역한 것이라서 한번에 안와닿고 이해하기 어려운 단어라고 생각한다 🥹
이해하기 쉽게 적어보자면..
옵셔널은 한 번 값을 설정한다면 이후에는 항상 값을 가질 수밖에 없다!
즉, 옵셔널은 항상 값이 있다고 생각할 수 있고
접근할 때마다 불필요한 확인과 언래핑은 필요없다는 뜻..!
타입 뒤에 물음표 대신 느낌표로 암시적으로 언래핑 된 옵셔널을 작성한다.
추가적으로 느낌표는 옵셔널 이름 뒤보다는 선언할 때 옵셔널 타입 뒤에 적어주는 것이 좋다.
하지만 !!
나중에 nil이 될 가능성이 조금이라도 존재한다면 사용 불가능하고 일반적인 옵셔널 타입 (물음표)를 사용해야한다.
let possibleString: String? = "An optional string."
let forcedString: String = possibleString!
// 일반 옵셔널
// ? 사용
// 언래핑 필요함.
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString
// 암시적으로 언래핑된 옵셔널
// ! 사용
// 언래핑 필요하지않음.