Swift - 열거형(Enum)

luminoux·2022년 5월 21일
0

Swift 문법

목록 보기
3/8
post-thumbnail

열거형

  • 연관된 항목들을 묶어서 표현할 수 있는 타입
  • 프로그래머가 정의해준 항목 값 외에는 추가/수정이 불가합니다.
  • 다음과 같은 경우에 요긴하게 사용할 수 있습니다.
    1. 제한된 선택지를 주고 싶을 떄
    2. 정해진 값 외에는 입력받고 싶지 않을 때
    3. 예상된 입력 값이 한정되어 있을 때

스위프트 열거형의 특징

  • 각 열거형이 고유의 타입으로 인정이 됩니다.

  • 원시값 (Raw Value)이라는 형태로 실제 값을 가질 수 있습니다.

  • 연관값 (Associated Value) 를 이용해서 다른 언어에서 공용체라고 불리는 값을 구현할 수 있습니다.

  • 보통 switch 구문과 함께 활용합니다.


enum School {
    case primaty // 유치원
    case elementary // 초등학교
    case middle // 중학교
    case high // 고등학교
    case college //대학
    case university //대학교
    case graduate //대학원
}
// 두 선언은 완벽하게 같은 선언입니다.
var universityStudent: School = School.university
//var universityStudent: School = .university
universityStudent = .graduate

1. 원시값(Raw Value)

  • 열거형의 각 항목은 자체로도 하나의 값이지만 원시값도 가질 수 있습니다.
  • .rawValue 를 이용하면 원시값에 접근할 수 있습니다.
  • 일부 항목에만 원시값을 줄 수도 있습니다.
import Foundation
enum School: String {
    case primary = "유치원"
    case elementary = "초등학교"
    case middle = "중학교"
    case high = "고등학교"
    case college = "대학"
    case university = "대학교"
    case graduate = "대학원"
}

var universityStudent: School = School.university
print("저의 최종학력은 \(universityStudent.rawValue) 졸업입니다.")

enum WeekDays: Character {
    case mon = "월"
    case tue = "화"
    case wed = "수"
    case thu = "목"
    case fri = "금"
    case sat = "토"
    case sun = "일"
}

let today: WeekDays = WeekDays.sat
print("오늘은 \(today.rawValue)요일 입니다.")

재밌는 점은 부분적으로 원시값을 지정했을 경우입니다.
스위프트가 알아서 원시값을 지정합니다.
정수형 원시값인 경우 +1 씩, 문자열인 경우, 이름을 그대로 반환합니다.


// primary의 경우에만 원시값을 지정했습니다.
enum School: String {
    case primary = "primary"
    case elementary
    case middle
    case high
    case college
    case university
    case graduate
}

var universityStudent: School = School.university
print("저의 최종학력은 \(universityStudent.rawValue) 졸업입니다.")
// 저의 최종학력은 university 졸업입니다.

// one의 경우만 원시값을 지정해보았습니다.
enum numbers: Int {
    case one = 1
    case two
    case three
    case four
    case five
    case six
    case seven
}

let number = numbers.six
print(number.rawValue)
// 6

열거형이 원시값을 갖는 열거형일 때, 열거형의 원시값 정보를 안다면, 원시 값을 통해 열거형 변수 또는 상수를 생성해줄 수 있습니다.
만약, 올바르지 않은 원시값을 통해 생성하려고 한다면, nil을 반환합니다.

enum School: String {
    case primary = "유치원"
    case elementary = "초등학교"
    case middle = "중학교"
    case high = "고등학교"
    case college = "대학"
    case university = "대학교"
    case graduate = "대학원"
}

let middleMan = School(rawValue: "중학교") // middle
let extraMan = School(rawValue: "어린이집") // nil

2. 연관값 (Associated Value)

  • Swift의 열거형 각 항목이 연관값을 가지게 되면, 기존 프로그래밍 언어의 공용체 형태를 띌 수 있습니다.
enum Food {
    case noodle(jumbo: String)
    case hamburger(numOfPatty: Int)
    case chicken(withSauce: Bool)
    case rice
}

var mainDish: Food = Food.hamburger(numOfPatty: 2)
mainDish = .chicken(withSauce: true)
mainDish = .noodle(jumbo: "곱배기")
mainDish = Food.rice

3. 열거형 항목 순회

  • 종종 열거형에 포함된 모든 케이스를 알아야할 경우가 생깁니다.
  • CaseIterable 프로토콜을 채택하면, 모든 케이스의 컬렉션을 생성해줍니다.
enum School: CaseIterable {
    case primaty // 유치원
    case elementary // 초등학교
    case middle // 중학교
    case high // 고등학교
    case college //대학
    case university //대학교
    case graduate //대학원
}

let allCases: [School] = School.allCases
print(allCases)

이렇게 단순한 열거형에는 CaseIterable 프로토콜을 채택해주는 것으로
모든 케이스를 확인해볼 수 있지만, Case가 복잡해질 경우 그렇지 않을 수 있습니다.
대표적인 예가 플랫폼별로 사용 조건을 추가하는 경우입니다.

enum School: String, CaseIterable {
    case primary = "유치원"
    case elementary = "초등학교"
    case middle = "중학교"
    case high = "고등학교"
    case college = "대학"
    case university = "대학교"
    
    //플랫폼 별로 구분
    @available(iOS, obsoleted: 12.0)
    case graduate = "대학원"
    
    static var allCases: [School] {
        let all:[School] = [.primary,
                            .elementary,
                            .middle,
                            .high,
                            .college,
                            .university]
        #if os(iOS)
        return all
        #else
        return all + [.graduate]
        #endif
    }
}

let allCase: [School] = School.allCases
print(allCase)

4. 순환 열거형

순환 열거형은 연관 값이 열거형 자신의 값이고자 할 때, 사용합니다.
indirect 키위드를 사용하면 됩니다.
특정 case에 한정하고 싶으면, case 앞에
enum 전체에 적용하고 싶다면, enum 앞에 키워드를 붙히면 됩니다.

// 덧셈, 곱셈 연산의 파라미터를 열거형 자신으로 사용할 수 있습니다.
enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
//parameter를 열거형 자신으로 받는 모습
let sum = ArithmeticExpression.addition(five, four)
let multi = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

func evaluate(_ expression: ArithmeticExpression) -> Int {
    switch expression {
        case .number(let value):
            return value
        case .addition(let left, let right):
            return evaluate(left) + evaluate(right)
        case .multiplication(let left, let right):
        return evaluate(left) * evaluate(right)
    }
}

let result: Int = evaluate(multi)
print(result)
profile
Apple Developer Academy @ Postech 2022

0개의 댓글