[오늘의 Swift 지식] Optional Binding이란? 🧐

2021. 8. 5. 20:10·📌 Swift
-->
이 글을 읽기 전에 Optional에 대해 자세히 모르시는 분은
이 글을 먼저 읽고 오시는 것을 추천드립니다. 😊

 



옵셔널 바인딩(Optional Binding)이란?

Optional Binding은 Optional 타입으로 선언된 변수에 값이 존재하는지 확인하고, 안전하게 값을 추출하는 기법입니다.

 

옵셔널 바인딩은 if let 또는 if var 구문을 사용하여 옵셔널 값을 안전하게 언래핑(Unwrapping) 할 수 있습니다.

 

옵셔널 값이 존재하면 if 구문 내에서 해당 값을 사용할 수 있으며, 값이 nil이면 if 구문이 실행되지 않고 건너뛰게 됩니다.

 

글만으로는 부족하니, 아래 코드를 보면서 보도록 할게요 😋

if let name = optionalName {
    print(name) // optionalName의 값이 존재하면 해당 값이 출력된다.
}
//
// optionalName의 값이 존재하지 않는다면, if문을 그냥 지나쳐서 이곳의 코드가 실행된다.

 

optionalName에 값이 존재한다면 name이라는 변수 안에 실제 값이 저장되고 if구문 내에서 그 값을 사용할 수 있게 됩니다. 

하지만, optionalName의 값이 'nil'이라면 if문은 그냥 지나치게 됩니다.

 

아래의 코드에서 보이듯이 하나의 if문에서 콤마(,)를 사용하여 여러 개의 옵셔널 값을 한 번에 바인딩 할 수 있습니다.

 

var optionalName: String? = "홍길동"
var optionalCountry: String? = "Korea"

if let name = optionalName, let country = optionalCountry {
    // name과 country 값이 존재
}
// name과 country 값이 둘 중 하나라도 존재하지 않는 경우

 

또한 optional binding을 통해 값을 추출한 후, 조건문을 추가하여 추가적인 작업을 수행할 수도 있습니다.

if let age = optionalAge {
    if age >= 20 {
        // age의 값이 존재하고, 20살 이상이다.
    }
}

 

Tip!! 코드가 많이 길어질 경우에는 아래와 같이 작성하여 가독성을 높이는 방법도 있습니다.

if let name = optionalName,
    let country = optionalCountry {
        // name과 country 값이 존재
    }
// name과 country 값이 존재하지 않는 경우

 

 

 

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

Optional Chaining은 이름에서 보이듯 "체인처럼 이어진다"는 느낌이라고 생각하시면 될 것 같은데요.

 

옵셔널 체이닝(Optional Chaining)은 객체의 프로퍼티, 메서드를 연결하여 호출하는 과정에서 nil 여부를 체크하는 방법입니다.

중간에 하나라도 nil이 발견되면, 전체 체이닝의 결과가 nil이 됩니다.

 

옵셔널 체이닝을 사용하여 프로퍼티에 접근하면, 원래 타입이 Int이든 String이든 상관없이 항상 옵셔널 타입(Int?, String?)으로 반환됩니다. 이렇게 되는 이유는 nil이 반환될 가능성을 고려하여 Swift가 자동으로 옵셔널 타입을 적용하기 때문입니다.

 

예제 코드를 보면서 설명을 하겠는데요, 아래 예제 코드는 [스위프트 언어 가이드 - Optional Chaining]에 나와있는 예제를 사용하였습니다.

 

처음으로, 'Person'과 'Residence'라는 두 개의 클래스를 정의합니다.

class Person {
    var residence: Residence?
}
// Person 클래스는 Residence 객체를 가리킬 수 있는 옵셔널 프로퍼티 residence를 가지고 있다.


class Residence {
    var numberOfRooms = 1
}
// Residence 클래스는 numberOfRooms라는 Int형 속성을 가지고 있으며, 기본값은 1이다.

 

아래의 코드에서 Person 타입의 인스턴스를 Jud로 생성해 줍니다.

let Jud = Person()

Jud의 프로퍼티 중 residence는 Residence? 타입의 옵셔널 프로퍼티이며, nil이거나 Residence 인스턴스를 가리킬 수 있습니다.

 

 

옵셔널 타입은 따로 초기화해주지 않으면 nil로 초기화가 되기 때문에, 위의 코드의 Jud에서 residence 속성 값은 nil이 되겠네요.

 

let roomCount = Jud.residence!.numberOfRooms
// this triggers a runtime error

위의 코드를 보면 밑에 주석 부분과 같이 오류가 생성됩니다. 그 이유는 Jud의 residence 속성 값이 nil인데, '!'를 사용하여 강제 언래핑(Forced Unwrapping) 하려고 하였기 때문입니다.

 

아래의 코드는 Jud.residence의 값이 nil이기 때문에, else문으로 넘어가서 코드가 실행되게 됩니다.

if let roomCount = Jud.residence?.numberOfRooms {
    print("Jud's residence has \(roomCount) room(s).")
} else {
    print("Unable to retrieve the number of rooms.")
}
// 출력 결과 : "Unable to retrieve the number of rooms."

위의 에러가 났던 코드에서는 nil인 값을 '!'를 사용하여 강제 언래핑(Forced Unwrapping)을 하려고 해서 오류가 났지만, 이번에는 '?'를 사용하여 강제 언래핑을 하지 않아서 오류는 생성되지 않습니다.

 

 

그런데 어느 부분에 옵셔널 체이닝을 사용한 건지를 설명하지 않은거같네요? 어느 부분에서 옵셔널 체이닝을 사용했을까요? 🤔

if let roomCount = Jud.residence?.numberOfRooms

바로 이 부분에 옵셔널 체이닝 방법을 적용하였습니다.

 

위 코드를 보면 옵셔널 체이닝(?.)을 사용하여 Jud.residence?.numberOfRooms에 접근하고 있습니다. Jud.residence가 nil이 아니라면 numberOfRooms를 확인하여 roomCount 변수에 방 번호가 포함되어 저장되겠네요.

 

만일, 위의 코드가 if문의 조건을 수행하여 "Jud's residence has 1 room(s)."라는 결과가 나타나도록 하려면,

Jud.residence = Residence()

라는 코드를 추가하면 되겠네요.

 

Optional에 대해 포스팅할 때 설명했지만, 다시 한번 강조하자면 '!'를 사용하는 '강제 언래핑(Forced Unwrapping)'은 가능하면 사용하지 않는 것이 좋습니다.

 

그 이유와 '!(강제 언래핑)'을 언제 사용하는지가 궁금하다면, 위에 남겨둔 링크의 Optional 설명 글을 보시는 것을 추천드릴게요 👍

 

 

 

Optional Binding에 대한 설명은 여기까지입니다.
이 글을 읽으신 분들이 있다면 조금이나마 도움이 되길 바라며,
오타나 틀린 점이 있으면 지적해주시면 감사하겠습니다 👋


References

Swift3 ) Optional 개념 정리

The Swift Programming Language - Optional Chaining

40시간 만에 Swift로 iOS 앱 만들기 - 옵셔널 (Optional)

 

 

 

 

'📌 Swift' 카테고리의 다른 글

[오늘의 Swift 지식] In-Out이란 무엇일까?  (0) 2021.08.24
[오늘의 Swift 지식] 전달인자(Argument)와 매개변수(Parameter)  (0) 2021.08.13
[오늘의 Swift 지식] if let과 guard let의 차이는?  (0) 2021.08.09
[오늘의 Swift 지식] 정렬 sort()와 sorted()  (0) 2021.07.17
[오늘의 Swift 지식] Optional이란? 🤔  (0) 2021.07.11
'📌 Swift' 카테고리의 다른 글
  • [오늘의 Swift 지식] 전달인자(Argument)와 매개변수(Parameter)
  • [오늘의 Swift 지식] if let과 guard let의 차이는?
  • [오늘의 Swift 지식] 정렬 sort()와 sorted()
  • [오늘의 Swift 지식] Optional이란? 🤔
MoriOS
MoriOS
기억하기 위해 기록하는 공간 🖋️
  • MoriOS
    MoriOS
    MoriOS
  • 전체
    오늘
    어제
    • 분류 전체보기 (50) N
      • 📌 Swift (10)
      • 📱 iOS (4)
      • 💡 Algorithm (1)
      • ❕Data structure (4)
      • 🪙 Python (0)
      • ⚙️ Git (2)
      • 🖋️ TIL Journal (26) N
      • 📝 Etc (3)
  • 블로그 메뉴

    • GitHub
  • 인기 글

  • 태그

    convenience init
    swift
    static
    swift 원시값
    편의 이니셜라이저
    Components
    TiL
    Split
    shuffled()
    github the requested url returned error: 403
    github 기반 협업 방식
    Optional
    random(in:)
    innerloop
    swift 열거형
    the requested url returned error: 403!
    swift 중복 없는 랜덤 숫자
    github 협업 방식
    후행클로저
    swift optional
    깃허브 로컬 복구
    클로저란?
    ios
    깃허브 복구
    swift 연관값
    GitHub
    weak
    트레일링 클로저
    구문 레이블
    enumerated()
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
MoriOS
[오늘의 Swift 지식] Optional Binding이란? 🧐
상단으로

티스토리툴바