본문 바로가기

IT/Swift

[swift] Optional, Optional Chaining

[swift 기초문법] - 옵셔널(Optional), 옵셔널체이닝(Optional Chaining)

 

옵셔널이란? (Optional)

swift에서 프로그램의 안전성을 높이기 위해 사용하는 개념으로 nil을 사용할 수 있는 타입을 가리켜 옵셔널 타입 이라고 부릅니다.

nil 일수도 아닐 수도 있다는 뜻으로 값이 있을 수도 없을 수도 있습니다.(nil은 값이 "없음"을 의미하는 특수한 값입니다.)

옵셔널로 선언된 변수 상수에만 nil을 할당할수 있습니다.

데이터(변수) 타입 뒤에 '?' 붙여 사용하여 옵셔널로 지정합니다.

 

var optInt: Int?

var value: String? = "test"
value = nil

/*
아래처럼 표현도 가능
그러나 '?'를 붙이는 게 더욱 간결하고 편함
*/
var value: Optional<String>

 

 

 

 

 

강제 추출(Forced Unwrapping)

옵셔널 값의 뒤에 '!' 를 붙임

 

var value: String? = "test"
var forcedvalue: String = value!

 

 

옵셔널 바인딩(Optional Binding)

옵셔널에 값이 있는지 확인할 때 사용
강제 추출은 런타임 오류를 유발할 가능성이 크므로 옵셔널 바인딩을 추천 
if 나 while 구문 등과 결합하여 상수나 변수로 할당해서 옵셔널이 아닌 형태로 가용할 수 있도록 함
',' 를 이용하여 여러 옵셔널을 한 번에 추출할 수도 있음

 

var myName: String? = "kjy" 
var yourName: String? = nil 

if let name = myName, let friend = yourName { 
	print("not in") 
} 

yourName = "yws" 

if let name = myName, let friend = yourName { 
	print("we are \(name) and \(friend)") 
}

 

 

암시적 추출 옵셔널(Implicitly Unrapped Optionals)

타입 뒤에 '!'를 붙
일반 값처럼 사용
널 값이 없다는 확신이 들 때 바인딩 하기 귀찮을 때 사용한다

 

var value: String! = "test"

 

 

 

옵셔널체이닝 이란? (Optional Chaining)

옵셔널일 수 있는 인스턴스 내부의 프로퍼티, 메소드, 서브스크립트를 매번 nil 체크를  하지않고 최종적으로 원하는 값, 혹은 nil 인지 판단하는 방법입니다.

여러개를 함께 연결 할수 있고, 연결된 어떤 링크라도 nil이면, nil이 됩니다.

하나의 링크라도 옵셔널이면 nil 값이 나옵니다.

 

//Family 클래서 내부에 Child 옵셔널타입 변수가 존재한다.
class Family {
    var child: Child?
}

//Child클래서 내부에 String 옵셔널타입 변수가 존재한다.
class Child {
    var name: String?
}

//Family 클래스 인스턴스 참조
//family 인스턴스의 child 프로퍼티는 옵셔널타입 이므로 child뒤에 ? 를 표시한다.
var family = Family()
family.child?.name = "c"

let name = family.child?.name
print(name) //출력: nil
/*
family.child?.name 프로퍼티가 "벨류값"로 할당 되었더라도 
family의 child 프로퍼티는 옵셔널 타입 이기때문에 nil 이 출력된다.
*/

 

 

만약 강제 언래핑을 한다면?

 

let name = family.child!.name
print(name)
/*error: Unexpectedly found nil while unwrapping an Optional value
name값이 nil 값인데 강제 언래핑을 하면 에러가 난다.*/

 

 

모든 링크에 인스턴스 참조 진행 후

 

//Family, Child 클래스 인스턴스 참조
var family = Family()
var child = Child()
child.name = "벨류값"

//family의 child 프로퍼티에 child 인스턴스 참조
family.child = child
let name = family.child?.name
print(name)
/*출력: Optional("벨류값") nil 값은 아닌 옵셔널값이 출력이 되었다.
 클래스 내부 프로퍼티에 인스턴스를 모두 참조 시켰지만 
 Family의 child 프로퍼티는 옵셔널타입이므로 옵셔널 해제를 진행해야 한다.*/

 

 

 

 

옵셔널체이닝 진행 후

 

//옵셔널 체이닝
if let name = family.child?.name {
    print(name)
} else {
    print("이름이 존재하지 않는다.")
}
/*출력: 벨류값
if let 문을 사용해서 값이 있을 때 옵셔널 해제를 해주었다.*/

 

 

중위 연산자를 사용해서 nil 값일때 들어갈 값을 지정해 준다면 옵셔널을 해제할 수 있다.

 

var name = family.child?.name ?? "이름이 존재하지 않는다."
print(name)
//출력: 벨류값

//중위연산자로 nil일 경우 사용할 값을 출력하기위해 nil로 만듬
family.child?.name = nil
name = family.child?.name ?? "이름이 존재하지 않는다."
print(name) //출력: 이름이 존재하지 않는다.

 

 

 

 

#swift 기초

#swift 강의

#ios programming

'IT > Swift' 카테고리의 다른 글

[swift] Closure, Capture list  (0) 2018.04.02
[swift] Mutating, Memberwise Initializers, Access Control  (0) 2018.03.13
[swift] Property  (0) 2018.03.12
[swift] Method, Struct, Class  (0) 2018.03.07
[swift] Operator, Flow Control  (0) 2018.03.06