본문 바로가기

Swift/Swift Language

Swift Enum의 RawValue 제대로 사용하기

스위프트의 Enum은 다형성을 지원하는 타입이다.

Enum의 rawValue를 String으로 사용할 때, 컴파일 시점에 안전하지 못하다.

예를 들어, 다양한 이미지 타입을 모델링하기 위해 다음과 같이 Enum을 정의하자.

enum ImageType: String { 
  case .jpg, .gif, .bmp, .unknown
}

 

ImageType의 rawValue를 읽어들어 어떤 적절한 값을 반환하는 함수를 정의하자.

 

func toImageType(for type: String) -> String {
  guard let imageType = ImageType(rawValue: type) else { return "unknown" }
  switch imgeType {
    case .jpg : return "jpg type"
    case .bmp : return "bit map type"
    case .gif : return "gif type"
  }

 

toImageType을 호출할 때, "jpg", "bmp", "gif"는 잘 변환이 될 것이다.
하지만 다음처럼 "JPEG", "JPG"와 같이 인자를 넘긴다면 .unknown 타입을 전달 받을 것이다.

 

let type1 = toImageType(for "JPEG") // "unknown"

 

이처럼 enum의 rawValue가 String일 경우에 컴파일 시점에 안전하지 못하다.

Enum 인스턴스를 초기화할 때 rawValue의 lowercase로 변환하여 넘겨주면 어떨까?

하지만 "jpg"는 "jpeg"로도 표현 된다. rawValue를 전환하기 전에 전처리 작업이 복잡해진다.

 

따라서, Enum 인스턴스를 생성할 때, 문자열 리터럴로 생성하려면 실패가능한 이니셜라이저(failable initializer)를 사용하는 것이 좋다.

enum ImageType: String {
  case .jpg, .gif, .bmp

  init?(rawValue: String) {
    switch rawValue.lowercased() {
    case "jpg", "jpeg": self = .jpg
    case "bmp", "bitmap": self = .bmp
    case "gif", "gifv": self = .gif
    default: return nil
  }
}

 

실패 가능한 이니셜라이저에서 옵셔널을 반환하기 위해 default 부분에서 nil을 반환하는 것에 주의하자.


Swift in Depth. Tjeerd in 't Veen. Manning. 2018