관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] Enum에서 초기화하는 테크닉 (~= 연산자) 본문

iOS 응용 (swift)

[iOS - swift] Enum에서 초기화하는 테크닉 (~= 연산자)

jake-kim 2022. 5. 9. 22:31

* Enum에 Equatable 프로토콜을 준수하여 만드는 방법) https://ios-development.tistory.com/348

Enum에 ~= 연산자 사용하여 init 만들기

  • 일반적인 경우, enum은 String을 준수하여 rawValue로 초기화가 가능
enum NamePrefix: String {
  case kim
  case lee
  case park
}

(rawValue로 초기화)

let namePrefix = NamePrefix(rawValue: "kim")
print(namePrefix) // Optional(ExEnum.NamePrefix.kim)
  • ~= 연산자를 사용하면, 손쉽게 equatable 속성으로 만들기가 용이
    • static으로 ~= 연산자를 정의
    • failable init으로 초기화 정의 (~=연산자가 정의 되었으므로, switch문으로 값 구분이 가능)
enum NamePrefix2: String {
  case kim
  case lee
  case park
  
  init?(name: String) {
    switch name {
    case .kim:
      self = .kim
    case .lee:
      self = .lee
    case .park:
      self = .park
    default:
      return nil
    }
  }
  
  static func ~=(lhs: Self, rhs: String) -> Bool {
    return lhs.rawValue == rhs
  }

}

let namePrefix2 = NamePrefix2(name: "kim")
print(namePrefix2) // Optional(ExEnum.NamePrefix2.kim)

associated value가 있는 경우 처리 방법

  • associated value가 존재하면 rawValue값을 사용하면 컴파일 에러가 나므로, String 준사하던 점을 걷어내기
enum NamePrefix2 {
  case kim
  case lee
  case park(age: Int?)
}
  • rawValue값을 사용하지 못하므로, ~= 연산자에서 비교할 값인 property 정의
  var name: String {
    switch self {
    case .kim:
      return "kim"
    case .lee:
      return "lee"
    case .park(let age):
      return "park"
    }
  }
  
  static func ~=(lhs: Self, rhs: String) -> Bool {
    return lhs.name == rhs
  }
  • switch 문에서 초기화
    • 주의할점은 associated value 값에 사용하는 아래 문법
    • case .park (age: nil)
  init?(name: String) {
    switch name {
    case .kim:
      self = .kim
    case .lee:
      self = .lee
    case .park(age: nil):
      self = .park(age: Int.random(in: 1...10))
    default:
      return nil
    }
  }
  • 전체 코드
enum NamePrefix2 {
  case kim
  case lee
  case park(age: Int?)
  
  var name: String {
    switch self {
    case .kim:
      return "kim"
    case .lee:
      return "lee"
    case .park(let age):
      return "park"
    }
  }
  
  init?(name: String) {
    switch name {
    case .kim:
      self = .kim
    case .lee:
      self = .lee
    case .park(age: nil):
      self = .park(age: Int.random(in: 1...10))
    default:
      return nil
    }
  }
  
  static func ~=(lhs: Self, rhs: String) -> Bool {
    return lhs.name == rhs
  }

}
  • 사용하는 쪽
let namePrefix2 = NamePrefix2(name: "park")

* 참고

https://stackoverflow.com/questions/47060366/custom-pattern-matching-fails-with-enum-case-is-not-a-member-of-type

Comments