예거's Bicycle for the mind

[Swift] Dictionary 의 옵셔널 반환에 대응하는 법 (default, nil 병합연산자) 본문

iOS & Swift

[Swift] Dictionary 의 옵셔널 반환에 대응하는 법 (default, nil 병합연산자)

유예거 2021. 9. 29. 23:40

스위프트의 Dictionary 는 Key와 Value를 pair(짝꿍)으로 묶어서 관리할 수 있는 Collection 타입이다.

Array(배열)와 다르게 순서가 없다. (Unordered Collection)

 

// 실험용 딕셔너리 생성
var items = [1: "운동화", 2: "티셔츠", 3: "목걸이", 4: ""]

// 키값을 통해 딕셔너리 안의 value를 꺼내올 수 있다.
items[1] // Optional("운동화")
items[4] // Optional("")

// 만약 딕셔너리에 존재하지 않는 키값이 입력되면, nil이 반환된다.
item[0] // nil

 

딕셔너리에서 키값(key)을 통해 value를 꺼내오면, 그 반환값은 기본적으로 옵셔널(Optional)이 된다.

딕셔너리에 존재하지 않는 키값이 입력되면 nil 이 반환될 수 있기 때문이다.

 

딕셔너리를 직접 정의한 개발자 입장에서는

"그 키값에 해당하는 밸류가 확실하게 존재하는데, 왜 옵셔널이지?" 라는 의문을 가질 수 있지만

 

컴파일러는 그런 걸 미리 알 수 없다.

그래서 nil 의 등장에 대비하기 위해, 기본적으로 모든 키값 요청에 옵셔널을 씌운다.

 

만약 키값에 해당하는 밸류가 없을 경우, nil 이 아니라 다른 값이 나오길 원한다면?

default: 를 이용할 수 있다.

요청하는 키값 옆에 콤마(,)를 찍고 대신 나올 값을 입력한다.

 

// default: 를 이용하면, 키값이 존재하지 않을 때 nil 이 아닌 다른 값을 반환한다.
items[0, default: "아이템이 없습니다."]
// 아이템이 없습니다.

 

이때, default 에는 String 타입만 들어갈 수 있다.

뜬금없이 Int, Double, Bool 타입을 집어넣으면 컴파일 에러가 난다.

defaut 또한, 딕셔너리를 만들 때 최초로 정의한 밸류의 타입과 동일해야 한다.

 

 

default 대신에 nil 병합연산자(nil-coalescing operator)를 사용할 수도 있다.

 

items[0] ?? "아이템이 없습니다."
// 아이템이 없습니다.

// 2번 이상의 nil 병합연산자 사용도 가능하다.
items[0] ?? items[5] ?? "아이템이 없습니다."
// 아이템이 없습니다.

 

만약 위에 예시에서, items[5]의 값이 존재했다면, 그 뒤에 String 인 "아이템이 없습니다."는 반환되지 않는다.

 

딕셔너리에 에러 케이스 넣어서 사용해보기

에러 핸들링은 enum(열거형), switch문, guard-let, if-let, do-try-catch 등과 자주 쓰인다.

특정 에러 발생 시, 출력할 에러 메시지를 딕셔너리 형태로 관리하면 어떨까?

 

// 열거형으로 에러 케이스 정의
enum SomeErrors: Error {
    case noItemKeyFound
    case noItemEnrolled
}

// 딕셔너리를 [열거형: String] 형태로 정의하여 에러 메시지 입력
let errorManual: [SomeErrors: String] = [
    .noItemKeyFound: "키값이 없습니다.",
    .noItemEnrolled: "아이템이 없습니다."
]

 

위와 같이 예시를 만들어서, 함수부터 do-try-catch 문 까지 만들어봤는데

결론은 "에러 메시지를 딕셔너리로 관리하면 불편하다." 라고 말하고 싶다.

 

왜냐면, 위에서도 얘기했듯이 딕셔너리는 반환값을 기본적으로 옵셔널로 꺼내기 때문

throw 로 넘겨받은 에러 케이스에 대한 메시지를 딕셔너리에서 뽑아내는 과정에서

불필요한 옵셔널 언래핑(optional unwrapping)이 요구된다.

 

강제 언래핑(force-unwrapping)을 여러번 사용하면 풀 수 있는 문제이지만

지금은 느낌표 사용(!)을 최소화하면서 공부하고 있으니.. 다른 방법을 또 공부해봐야겠다.

Comments