[Swift] 열거형(Enum)

Jay SJ Baek·2021년 3월 10일
0

Swift Basic

목록 보기
5/8
post-thumbnail

열거형(enum)

  • 제한된 선택지를 주고 싶을 때
  • 정해진 값 외에는 입력받고 싶지 않을 때
  • 예상된 입력 값이 한정되어 있을 때
  1. 각각의 케이스가 값으로 취급된다.
  1. C언어의 열거형에서는 정수값이 자동으로 할당되지만 Swift에서는 작동 방식이 다르다. Swift에서는 각 항목이 그 자체로 고유값이 될 수 있다.
  1. 처음 선언시에는 열거형을 명시해줄 필요가 있다.
enum Weekday {
  case mon
  case tue
  case wed
  case thu, fri, sat, sun
}


var day: Weekday = Weekday.mon
  1. enum이 정수값을 가지면 rawValue를 생성해줄 수 있고 이 rawValue는 첫번째 case가 값이 정해지면 C언어처럼 1씩 증가한다.
    • 1씩 증가하다가 중간에 중복되지 않는 다른 수가 생길 경우 그 수부터 시작해서 다음 케이스는 다시 1씩 증가한다.
enum School: Int {
  case elementary = 0
  case middle = 1
  case high

// case univ = 0 면 elementary의 원시값과 겹치므로 정의 불가
// high는 자동적으로 2가 할당됨
}

enum Fruit: Int {
  case apple
  case orange
}

let fruit = Fruit.apple
print(fruit.rawValue) // 0

// 첫번째 case의 rawValue를 설정하지 않을 경우 0으로 시작
  1. enum이 String일 경우 rawValue를 예측할 수가 없기 때문에 rawValue를 불러오면 그 case의 이름 그대로를 가져온다.
enum Beverage: String {
  case water = "물"
  case wine = "와인"
  case beer = "맥주"
  case juice
}

print("Beverage.water.rawValue == \(Beverage.water.rawValue)")
// Beverage.water.rawValue == 물

// 열거형의 원시값 타입이 String일 때, 원시값이 지정되지 않았다면
// case의 이름을 원시값으로 사용합니다
print("Beverage.juice.rawValue == \(Beverage.juice.rawValue)")
// School.middle.rawValue == juice
  1. rawValue를 통해 초기화 할 수 있다.

    • rawValue를 기준으로 가져올 때, 주어진 rawValue에 해당되는 case가 없을수도 있기 때문에 optional로 정의된다.
    • rawValue에 직접적으로 할당하는 것을 불가능하다.
   let grapeJuice: Beverage = Beverage(rawValue: 3) // 에러 발생 -> rawValue로 접근한 Beverage는 optional이므로
   
   let grapeJuice: Beverage? = Beverage(rawValue: 3)
   
   if let strawberryJuice: Beverage = Beverage(rawValue: 3) {
       print("\(strawberryJuice)")
   } else {
       print("해당 쥬스가 없습니다.")
   }
   
   // 직접할당 불가
   let fruit = Fruit.apple
   fruit.rawValue = 10 // Cannot assign to property: 'rawValue' is immutable 에러 발생
  1. 메서드

    • 열거형에는 메서드를 추가 할 수 있다.
    enum Month {
        case dec, jan, feb
        case mar, apr, may
        case jun, jul, aug
        case sep, oct, nov
        
        func printMessage() {
            switch self {
            case .mar, .apr, .may:
                print("봄")
            case .jun, .jul, .aug:
                print("여름")
            case .sep, .oct, .nov:
                print("가을")
            case .dec, .jan, .feb:
                print("겨울")
            }
        }
    }
    
    Month.mar.printMessage()
  1. Swift의 enum은 raw value type으로 tuple을 가질 수 없다.

    typealias nameAndNumber = (name: String, number: Int)
    
    enum Fruit: nameAndNumber { // 에러 발생
        case apple = ("apple", 10)
        case orange = ("orange", 10)
        case watermelon = ("watermelon", 10)
    }
    
    // 위의 코드를 굳이 튜플로 만든다면 struct를 활용할 수 있다.
    struct Fruit {
        static let apple = ("apple", 10)
        static let orange = ("orange", 10)
        static let watermelon = ("watermelon", 10)
    }
  1. 항목 순회

    • 열거형에 포함된 모든 케이스를 알아야할 경우 enum의 타입 뒤에 CaseIterable을 선언해주면 allCases를 통해 항목의 모든 케이스의 컬렉션을 생성해준다.

      enum Beverage: String, CaseIterable {
        case beer = "beer"
        case wine
        case juice
        case water
      }
      
      let allCases: [Beverage] = Beverage.allCases
      print(allCases)
      print(type(of: allCases))
      // 출력
      // [__lldb_expr_17.Beverage.beer, __lldb_expr_17.Beverage.wine, __lldb_expr_17.Beverage.juice, __lldb_expr_17.Beverage.water]
      // Array<Beverage>

10 . 순환 열거형

  • 열거형 항목의 연관 값이 열거형 자신의 값이고자 할 때 사용
  • indirect 키워드를 사용
  • 특정 항목에만 한정하고 싶다면 case 키워드 앞에 indirect, 열거형 전체에 적용하고 싶으면 enum 키워드 앞에 indirect를 붙인다.
  • 열거형 항목을 사용한 결과물이 다시 자신의 열거형 항목일 때(?)
  1. 비교 가능한 열거형

    • Comparable 프로토콜을 채택하면 각 케이스 비교가 가능하다.

    • 앞에 위치한 case가 더 작은 값이 된다.

      enum School: Comparable {
          case elementary
          case middle
          case high
          case univ
      }
      
      let mySchool = School.univ
      let yourSchool = School.high
      
      if mySchool > yourSchool {
          print("I'm older")
      }

reference: Swift Programming by 야곰

profile
iOS Developer

0개의 댓글