이 포스팅은 Swift 시리즈 20 편 중 18 번째 글 입니다.

  • Part 1 - 01: Optional, Any, AnyObject, nil
  • Part 2 - 02: struct, class, enum
  • Part 3 - 03: Closure
  • Part 4 - 04: Property
  • Part 5 - 05: 상속, 생성자, 소멸자
  • Part 6 - 06: 옵셔널 체이닝과 nil 병합
  • Part 7 - 07: 타입 캐스팅
  • Part 8 - 08: assert, guard
  • Part 9 - 09: Protocol
  • Part 10 - 10: Extention
  • Part 11 - 11: 오류처리
  • Part 12 - 12: 고차함수
  • Part 13 - 13: ARC(Automatic Reference Counting)
  • Part 14 - 14: Access control, Access modifier
  • Part 15 - 15: Generics
  • Part 16 - 16: Optional에 대한 깊은 이해
  • Part 17 - 17: Lazy Variables
  • Part 18 - This Post
  • Part 19 - 19: Initialization
  • Part 20 - 20: Concurrency
▼ 목록 보기

연관값 없이 enum 비교하기

  • 이게 코딩을 하다보면, 분명 enum 값은 다른데, 내부 연관값자체는 필요없고, 타입 자체만 비교하고 싶을 수 있다.
  • 예를 들어 바코드 열거형이 있다고 하면, 하나는 흔히 아는 1차원 바코드, 2차원 바코드(QR)이 있을 수 있겠다.
  • 각각이 필요한 값들은 다르고, 그 값을 연관 값에 지정했다고 해보자.
  • 그런데 내가 코드를 짜다보니, 그냥 저 연관값 말고, QR이면 QR, 바코드면 바코드 자체만 구분하고 싶을 수 있다.
  • 그런데 스위프트에서는 그게 안된다.
let a = SomeClass()

if a.barcode == BarCode.QR {
  // not working
}

if a.barcode == BarCode.QR(a: ~, b: ~) {

}

아래와 같은 방식으로 비교하라고 친절히 알려준다. 이런 상황에서의 해결방법이 필요하다.

해결

var humans: [Player] {
    self.players.filter { player in
        if case PlayerType.human = player.type {
            return true
        }
        return false
    }
}
  • 나같은 경우는 아래 Reference에서 답을 찾았는데, 위와 같이 비교하면 된다고 한다.

Pattern matching

  • 이걸 이해하려면 pattern matching에 대해 알아야 한다.
  • 일단 다른 방법으로 위와 같은 방식을 할 수 있는지 알아보자.
enum Media {
  case book(title: String, author: String, year: Int)
  case movie(title: String, director: String, year: Int)
  case website(urlString: String)
}

let m = Media.movie(title: "Captain America: Civil War", director: "Russo Brothers", year: 2016)

if case let Media.movie(title, _, _) = m {
  print("This is a movie named \(title)")
}
  • 자, 제대로 알아보니, 일단 첫번째. 뒤에 연관값을 생략해버린 것이 내가 사용한 문법이라는 것을 알 수 있다.
  • 그러면 이 문법의 정체는 무엇인가?
switch m {
  case let Media.movie(title, _, _):
    print("This is a movie named \(title)")
  default: () // do nothing, but this is mandatory as all switch in Swift must be exhaustive
}
  • 정체는 switch 였다. 그런데 이렇게 쓰기 싫잖아? 그러니 if case로 써버리자.
  • 추가적인 친구들로 guard case, for case 등이 있다.
  • 이러한 것들은 내가 루프를 돌 일이 있거나, 빼내야 할 때 알아보자.

Reference