스위프트의 옵셔널

개요


C언어에는 없고 스위프트에만 있는 기능 옵셔널에 대해서 알아보겠다.




옵셔널


옵셔널은 말 그대로 값이 있을 수도 없을 수도 있다.

값이 없다는 것은 NULL 상태라는 의미이고 스위프트에서의 NULL은 nil이다.

따라서 옵셔널은 nil값을 할당할 수 있는 유일한 방법이다.

옵셔널에 값이 할당되었다면 wrapped라고 부르며 값을 사용할 때는 forced unwrapping이라고 한다.




선언 방법


? 혹은 Optional을 타입에 붙여서 사용한다.

1
2
3
4
5
6
7
8
var exOp: String? = "kyujin"
exOp = nil

var exOp2: Optional<String> = "kyujin"
exOp2 = nil

var exOp3 = Int("10") //optional<Int>
var exOp4 = Int(10) // <Int>




사용 이유


옵셔널 타입을 쓰는 이유는 변수, 상수에 값이 할당되지 않은 상황을 처리하기 위해 안전한 접근 방식을 제공하기 위해서이다.

함수의 인자값이 잘못되어 오류를 알릴 때 nil을 반환하면서 표현할 수 있다.

매개변수에 인자값을 전달하는 것이 필수가 아닐때도 옵셔널로 할 수 있다.




옵셔널 추출


열거형 안에 some 케이스로 옵셔널 추출을 할 수 있다.



강제 추출


런타임 오류가 발생할 수 있다. 대표적으로 옵셔널 값이 없다면 발생한다.

강제로 하기 때문에 옵셔널의 의미가 없을 수 있다.

옵셔널 뒤에 !를 붙이면된다.

1
2
3
4
5
6
7
8
9
10
var exOp: String? = "kyujin"
exOp = nil

var exOp2 = exOp! // Error

if exOp != nil {
  print(exOp!)
} else {
  print ("nil")
}



옵셔널 바인딩


옵셔널에 값이 있는지 확인하고 있다면 상수 혹은 변수에 저장한 다음 일정 블록안에서 변수나 상수처럼 사용가능하다.

1
2
3
4
5
6
7
8
var exOp: String? = "kyujin"
exOp = nil

if let name = exOp {
  print("valid value")
} else {
  print ("nil value")
}



암시적 추출 옵셔널


!를 사용하여 오류가 나지 않을 것 같을 때 사용할 수 있다.

1
2
3
var exOp: String! = nil

exOp.isEmpty //Error




옵셔널 체이닝


옵셔널 체이닝이란 프로퍼티, 메서드, 서브스크립트가 nil값인지 아닌지를 연쇄적으로 확인하는 것이다.

만약 옵셔널이 값을 가지고 있다면 다음 옵셔널 값을 체크하거나 다음 구문을 실행하지만 nil값이라면 nil을 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Person {
  public var residence: Residence?
}

class Residence {
  public var room = 1
}

let kyujin: Person?
kyujin = Person()

//옵셔널 체이닝 사용
if kyujin?.residence?.room != nil {
  print("yes")
} else {
  print("no")
}

//옵셔널 체이닝 미사용
if let kyu = kyujin {
  if let resi = kyu.residence {
    print ("yes")
  } else {
    print ("no")
  }
} else {
  print("no")
}

// result : no - because of residence