본문 바로가기
Swift/기본

옵셔널

by 밤새는탐험가 2024. 3. 29.

옵셔널

변수 뒤에 붙는 ? 물음표가 바로 옵셔널이다.

옵셔널 변수는 값이 있을 수도 또는 없을 수도 있다는 의미이다.

 

name이라는 변수에 String 타입으로 "jerry"라는 값을 할당했다.

var name: String = "jerry"
print(name)

// jerry

 

 

근데 만약에 name이라는 변수에 들어갈 값이 아직 정해지지 않았다면?

String 타입 뒤에 ? 물음표를 붙인다. 

그러고 print()로 출력하면 nil이 출력된다. 

 

var name: String?
print(name)

 

 

나중에 name이라는 변수에 값을 할당한다면?

그리고 출력하면 Optional("jerry")가 나온다. 

 

var name: String? = "jerry"
print(name)

// Optional("jerry")

 

 

Optinal()로 감싸져서 나온 값이랑 그렇지 않은 값은 연산이 가능한가?

그렇지 않다. 

예를 들어 Int 타입의 두 변수 중 하나는 옵셔널로 선언할 경우 

두 변수의 연산은 안된다. 

오류가 뜨는데 옵셔널 타입을 해제해야 한다고 한다. 

 

 

 

Optional() 해제

 

1. Force Unwrapping (강제 해제)

변수명 뒤에 ! 느낌표를 붙여준다. (추천하지 않음)

 

var name: String?
print(name!)

 

이 경우에 nil이 출력된다. 

다만, Expression implicitly coerced from ‘String?’ to ‘Any’ 라는 warning 이 뜨게 되는데 

이 경우에는 nil일 경우에 대비한 기본값을 할당하면 된다. 

 

var name: String?
print(name ?? "이름 없음")

 

 

2. Optional Binding

강제 해제는 오류가 발생할 위험이 있기 때문에 추천하지 않는다.

안전하게 값에 접근하기 위해서는 Optional Binding을 쓴다. 

 

  • if let
  • guard let

 

 

if let 을 이용하여 Optional Binding 하는 경우

name 이라는 옵셔널로 선언한 변수에 "jerry" 라는 값을 할당했다. 

함수 checkName 안에 if let을 이용하여 옵셔널 바인딩을 처리했다. 

var name: String? = "jerry"

func checkName(name: String?) {
    if let checkName = name {
        print("이름 : \(checkName)")
    } else {
        print("없음")
    }
}

checkName(name: name)  // 이름 : jerry

 

 

name 이라는 변수에 값이 없었다면 "없음"이라고 출력된다. 

var tom: String?
checkName(name: tom)   // 없음

 

 

guard let 을 이용하는 경우 

guard let은 함수에서만 사용할 수 있기 때문에 함수로 만들어 사용한다.

guard의 조건을 만족하지 못하면 else 구문 블럭 내의 print() 와 return을 반환하고,

만족하면 print() 출력한다. 

var apple: String? = "Apple"
var banana: String = "banana"
var kiwi: String?

func checkFruit(name: String?) {
    guard let fruitName = name else {
        print("과일 이름 없음")
        return
    }
    print("과일 이름: \(fruitName)")
}

checkFruit(name: apple)    // 과일 이름: Apple
checkFruit(name: banana)   // 과일 이름: Banana
checkFruit(name: kiwi)     // 과일 이름 없음

 

 

  • if let: 값의 유무를 확인 후, 있을 때 없을 때 각각의 코드를 실행
  • guard let: 값의 유무를 확인 후, 값이 없으면 함수를 실행하지 못하도록 방어
  • 복잡도: if let > guard let

 

'Swift > 기본' 카테고리의 다른 글

클래스 (Class)  (0) 2024.04.01
구조체 (Struct)  (0) 2024.04.01
반복문  (0) 2024.03.26
조건문  (0) 2024.03.26
함수 고급  (0) 2024.03.22