Swift/Swift 문법 정리

[iOS / Swift] Optional 개념과 Unwrapping 정리

이도서 2024. 12. 19. 20:17

iOS 개발하면서 Optional 개념은 필수로 알아야 함. Swift에서 값이 없을 수도 있다는 걸 표현하려면 Optional을 써야 함. 이번 포스팅에서는 Optional 기본 개념, Unwrapping, Optional Binding에 대해서 정리해볼 것임.

 

1. Optional 이란? 🤔

let num: Int? = nil // 값이 없음
let name: String? = "Doseo" // 값이 있음

Optional 타입 변수는 값이 없을 때 nil을 저장할 수 있음. 반면, Non-Optioanl(일반 타입) 타입 변수는 무조건 값을 가짐.

 

2. Optional 값 사용하기: Unwrapping 🫢

Optional 값을 사용하려면 Unwrapping이 필요함.

 

(1) 강제 Unwrapping

: !를 붙여서 값을 강제로 꺼낼 수 있음.

let optionalNum: Int? = 123
print(optionalNum!) // 123

하지만, Optional 값이 nil일 경우 강제 Unwrapping하면 런타임 에러가 발생함.

let optionalNum: Int? = nil
print(optionalNum!) // 런타임 에러 🚨

 

(2) Optional Binding

: 강제 Unwrapping 대신 Optional Binding을 써서 안전하게 값을 꺼내는 방법임.

if let str = str { 
    if let num = Int(str) { 
        print(num) // 123
    } else {
        print("타입 변환 실패")
    }
} else {
    print("옵셔널 바인딩 실패")
}

 

3. 자주쓰는 Optional 패턴 👍

Optional을 사용할 때 자주 쓰는 패턴을 몇가지 정리해봄

 

(1) guard let을 활용한 Unwrapping

: guard let은 조건이 맞지 않으면 초기 단계에서 바로 빠져나감.

func processString(_ input: String?) {
    guard let unwrapped = input else {
        print("입력값이 nil임")
        return
    }
    print("입력값은 \(unwrapped)임")
}

 

(2) 기본값 제공 (?? 연산자)

: Optional 값이 nil이면 기본값을 설정할 수 있음.

let optionalName: String? = nil
let name = optionalName ?? "Default Name"
print(name) // "Default Name"

 

4. Optional 관련 주의할 점  🚨

  1. 강제 Unwrapping은 필요한 경우에만 하셈. 값이 nil일 때 앱이 크래시 날 수 있음
  2. Optional Binding을 자주 쓰셈. if let, guard let 등을 쓰면 안전하게 코드 작성 가능
  3. Optioan과 Non-Optional의 차이점을 알아두셈. Optional 타입은 Non-Optional 타입과 호환 안 됨. 따라서 적절한 Unwrapping이 필요함.

5. 결론 ✍️

Swift에서 Optional은 처음엔 어렵게 느껴질 수 있지만, 익숙해지면 코드 안정성을 높여주는 좋은 도구임. 강제 Unwrapping보다는 Optional Binding과 guard let을 자주 쓰는 게 좋음.

 

아래는 내가 공부하면서 정리한 전체 코드랑 코드 파일임. 필요하면 참고하셈.

import UIKit

// Non-Optional, Non-Optional Type

//let num: Int
//num = 123
//
//print(num)


// Optional로 선언
//let num1: Int? // 뒤에 물음표를 붙임
//num1 = nil // null, 값을 nil로 저장하면 값을 저장하지 않는다 라고 생각하면 됨
//
//let attendeeCount: Int? = nil
//
//let name: String? = ""

//let num = 123
//
//print(num)


// Unwrapping, 추출
// 강제 언래핑을할거면 뒤에 !를 붙이면 됨

let optionalNum: Int? = 123
//print(optionalNum) 이렇게하면 값이 들어있는 것
print(optionalNum!) // 이렇게하면 강제 언래핑

//let optionalNum1: Int? = nil
//print(optionalNum1!) 이렇게하면 옵셔널 값이 없는데 강제 언래핑해서 값이 nil이라 추출할 값이 없기 때문에 오류 발생

let a = optionalNum
print(type(of: a))

let b = optionalNum! // 이건 강제 언래핑을한 상태이므로 옵셔널 Int가 아닌 그냥 Int타입


//let str = "123"
//let num1 = Int(str)
//print(type(of: num1)) // 이렇게하면 Optional<Int>로 저장됨 형변환에 실패할 수 있기 때문

let str: String? = "123"
let num = Int(str!)

//let str: String? = "123"
//let num = Int(str) 옵셔널 값을 전달할 수 없음 str뒤에 !를 붙이면 가능. but, 값이 nil이 아닐때 가능

// optional binding 하는 방법. 중요함!!
// if let name : Type = OptionalExpreesion {
//    statements
// }
//
// while let name : Type = OptionalExpreesion {
//    statements
// }
//
// guard let name : Type = OptionalExpression else {
//    statements
// }

if let str = str { // = str은 생략해도 되긴 함
    if let num = Int(str) { // 지금 if에서 선언한 str을 말하는 것임 위에 있는 str이 아님
        print(num)
    } else {
        print("타입 변환 실패")
    }
} else {
    print("옵셔널 바인딩 실패")
}

// 위 경우 let str: String? = "123"인 경우는 123이출력
// let str: String? = nil인 경우는 옵셔널 바인딩 실패 출력
// let str: String? = "nil"인 경우는 타입 변환 실패 출력

 

Optionals.playground.zip
0.01MB