nil 의미
nil of Swift : 값이 없다 in 모든 타입 (Reference or Value Type)
즉, Swift에서는 어떤 타입이든 값이 없는 것을 표현하기 위해 nil을 사용한다.
아래와 같은 경우는 에러가 난다.
var name: String = "Seungwan"
name = nil //컴파일 에러!
Optional Type
값이 있을 수도 있고 없을 수도 있는 변수를 정의할 때에는 타입 어노테이션에 ?
을 붙여서 표현한다. 이렇게 정의한 변수를 Optional이라고 한다. Optional에 초깃값을 지정하지 않으면 기본값은 nil
이다.
var name: String?
print(name) //nil
name = "wowowo"
print(name) //wowowo
Optional로 정한 변수는 아래와 같은 바인딩이 안된다.
let optional: String? = "this is option"
let notoptional: String = optional //error
notoptional
변수는 Optional이 아닌 String
이기 때문에 항상 값을 가지고 있어야하는데, optional
변수는 실제 코드가 실행되기 전까지는 값이 있는지 없는지 알 수 없기 때문에 Swift에서는 저런식의 바인딩은 안된다.
Optional은 개념적으로 어떤값
또는 nil
을 가지고 있는 변수기 때문에 불완전한 변수라고 생각하면 쉽다.
Optional Binding
Optional 바인딩은 Optional의 값이 존재하느지를 검사한 뒤, 존재한다면 그 값을 다른 변수에 대입시켜준다. if let
또는 if var
를 사용해서 한다. Optional변수에 값이 존재하면 if안에서 처리하고 nil이면 그냥 if문을 통과한다.
그리고 하나의 if
문에서 콤마(,)로 구분해서 여러개의 Optional을 바인딩할 수 있다.
var name: String? = "seunwan"
var email: String? = "wh7923@gmail.com"
if let name = name, email = email{
// name과 email 값이 존재
}
저게 너무 길어지면 아래와 같이 해도 된다.
if let name = name,
email = email{
//name과 email존재
}
조건도 넣을 수 있다.
var optionAge: Int? = 25
if let age = optionAge, age >= 20 {
//age 값이 존재하고, 20이상이다.
}
//아래와 같다.
if let age = optionAge {
if age >= 20 {
//age의 값이 존재하고, 20 이상이다.
}
}
Optional Chaining
Swift 코드를 간결하게 만들어주는 요소이다.
Optional로 선언된 어떤 배열이 있다. 이 배열이 ‘빈 배열’인지를 검사할려면 다음과 같다.
let array: [String]? = []
var isEmptyArray = false
if let array = array where array.isEmpty {
isEmptyArray = true
} else {
isEmptyArray = false
}
isEmptyArray
Optional 체이닝을 사용하면 간결하게 표현이 가능하다.
let isEmptyArray = array?.isEmpty == true
?
키워도로 코드를 줄여주는 역할을 한다.
한가지 예를 더 들면 다음과 같다.
class Person{
var live: Home?
}
class Home{
var adress: Location?
}
class Location{
var zipnum: String?
}
let seungwan = Person()
seungwan.live = Home()
seungwan.live?.adress = Location()
seungwan.live?.adress?.zipnum = "171717"
if let home = seungwan.live{
if let zip = home.adress{
if let num = zip.zipnum{
print(num) //171717
}
}
}
if let num = seungwan.live?.adress?.zipnum{
print(num) //171717
}
코드가 간결해 지는 것을 알 수 있다.
Unwrapped Optional
print(optionEmail) // Optional("wh7923@gmail.com")
print(optionEmail!) // wh7923@gmail.com
여기서 주의 할 점은 !
을 사용할 때 Optional값이 nil
인 경우에는 런타임 에러가 발생한다.
var optionEmail: String?
print(optionEmail!) //런타임 에러!
Implicitly Unwrapped Optional
Optional을 정의할 때 ?
대신 !
을 사용하면 ImplicitylyUnwrappedOptional
이라는 Optional로 정의 된다.
var email: String! = "wh7923@gmail.com"
print(email) //wh7923@gmail.com
이렇게 정의된 Optional은 nil
을 포함할 수 있는 Optional이긴 한데, 접근할 때 Optional 바인딩이나 Optional을 벗기는 과정을 거치지 않고도 바로 값에 접근할 수 있다는 점에서 다르다.
Optional 벗기기와 마찬가지로, 값이 없는데 접근을 시도하면 런타임 에러가 발생한다.
var email: String!
print(email) //런타임에러!