Joswlv

Optional

2016-10-24

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) //런타임에러!


Reference


Comments