요즘 유튜브를 통해 iOS 어플 만들기에 도전하고 있는데, 코딩을 하다보면 생소한 것들이 있다. 대표적으로 변수 뒤에 ?
나 !
가 붙는 경우가 있는데, 이게 무엇인지 궁금했다. 이것들은 Optional 이라고 정의하는 개념이다.
Optional은 Type Casting이나 nil value 체크 등에 있어서 중요한 역할을 한다. Optional은 ?
을 통해 표현되는데, 그 의미는 다음과 같다.
이 변수에는 값이 들어갈 수도 있고, 아닐 수도 있다.(nil)
일단 여기 nil value 라는 개념이 생소하기 때문에, 이것을 먼저 알아보자.
nil은 c에서 흔히 쓰던 NULL과 비슷하지만 조금 다르다.
// c-pointer의 부재 및 c나 c++의 변수 및 객체에 사용한다.
int *intPtr = NULL;
var optionalString: String?
var optionalString2: String? = nil
// 두 값 모두 nil이다.
nil
은 Swift에서 value
가 없는 것을 의미한다.
그리고 optional 변수 이외에서 사용 불가. 그리고 따로 초기화하지 않아도 기본으로 설정된다.
Optional의 기본적인 형태는 다음과 같다.
let myFirstOpVar : Int?
위처럼 변수 타입의 뒤에 ?
를 붙여주면 해당 변수는 Optional 변수가 된다. Swift에서는 기본적으로 변수 선언시에 nil 값이 들어가는 걸 허용하지 않는다고 한다. (심지어 런타임 에러가 아니라 아예 컴파일 에러를 내버린다.)
var OpString: String = nil // 컴파일 에러
var OpString2: String? = nil // Optional이므로 정상
다음 예시는 String -> Int
로 Type Casting 하는 경우이다.
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
print(convertedNumber)
>>> Optional(123)
let convertedNumber = Int(possibleNumber)!
print(convertedNumber)
>>> 123
첫 번째 경우, "123"은 String 이기 때문에 Int(possibleNumber)
초기화에 실패한다. 이 경우 바로 에러가 나오는게 아니라 Optional Int형으로 선언한다.(Int는 아님) 그래서 두번째 경우처럼 뒤에 !
를 붙여서 unwrap(뒤에나올 내용)을 해주면 Int로 형 변환이 된다.
Optional과 뗄 수 없는 관계가 Wrapping 이라는 개념이다.
Optional타입은 기본적으로 wrap되어 있는 상태이다. 즉, Optional 변수들은 현재 값이 존재하는 것인지, nil은 것인지 wrap되어 있어서 모른다고 보면 된다. 그렇기 때문에 wrap 된 상태에서는 value값이 있는지 없는지에 관계 없이 바로 value가 출력되지 않는다.
var opString : String? = "Hello"
print(opString) // opString은 optional 이다.
>>> Optional("Hello")
우리는 변수들을 출력할 때 앞의 경우처럼 Optional("Hello")
이렇게 나오는 것을 대부분 바라지 않는다. 이 때 올바른 출력을 위해 사용하는 것이 !
이다. Optional로 선언했지만, 변수에 value가 있는 상황이 보장된 경우 !
를 사용하면 우리가 원하는 출력값을 얻을 수 있다.
var opString : String? = "Hello"
print(opString!)
>>> Hello
즉, wrap되어 있는 Optional 변수를 unwrap 한다고 할 수 있다. 우리가 원하는 출력값은 unwrap 되어 있는 상태에서만 얻을 수 있는 것이다.
주의해야 할 점은, 변수에 값이 있다고 확신한 상태에서만 unwrap을 할 것.(그렇지 않으면 런타임 에러가 발생한다.)
따라서 보통은 unwrap하기 전에 nil인 경우를 체크하고 unwrap 한다.
let value2: String? = nil
if value2 != nil { // nil 체크.
print(value2)!
}
Optional Binding은 Optional 타입으로 선언된 변수에 값이 있는지 없는지를 확인할 수 있도록 해주는 기능이다. Optional Binding을 사용하면 느낌표 없이 Optional 타입의 변수 값을 출력할 수 있어서 좀 더 안전한 형태로 값을 얻을 수 있다. 기본적인 형태는 다음과 같다.
if let 변수명 = Optional 변수 {
// 임시 변수에 Optional 변수의 value값이 할당된다다.
}
형태만 봐서는 잘 이해가 되지 않으므로 예제를 봐보자.
// Optional type으로 선언한 myNumber
let myNumber: Int? = 1234
if let actualNumber = myNumber {
print(“\(myNumber)은 실제로 \(actualNumber)입니다.”)
} else {
print(“\(myNumber)는 변환될 수 없습니다.”)
}
// 출력 결과 : Optional(1234)은 실제로 1234입니다.
print(actualNumber) // error
여기서 myNumber
변수는 Optional 타입으로 선언되어 있는데, Optional Binding은 이 변수의 값이 있는 지 없는 지 판단하고, 값이 있는 경우 if let 조건문을 실행한다고 생각하면 된다.
actualNumber
에 myNumber
값을 할당하고, 값이 있다면 바로 실제값으로 사용할 수 있도록 해준다. 추가적으로, actualNumber
는 if문 안에서만 사용 가능하고, 밖에서는 사용 불가능하다!
nil 체크 + nil이 아닌 경우에 새로운 변수로 바꿔주는 기능을 if let 한줄에 할 수 있게 해주는 굉장히 유용한 기능이다.
출처 : Swift Optional(1)