데이터 타입 고급 - 열거형

hoBahk·2021년 6월 21일
0

열거형

열거형은 연관된 항목들을 묶어서 표현할 수 있는 타입이다. 열거형은 아래와 같은 경우 사용하면 좋다.

  • 제한된 선택지를 주고 싶을 때
  • 정해진 값 이외에는 입력받고 싶지 않을 때
  • 예상된 입력 값이 한정되어 있을 때

1. 기본 열거형

ex) 열거형의 선언

enum School1{
    case primary
    case elementary
    case middle
    case high
    case college
    case university
    case granduate
}

enum School2{
    case promary, elemetary, middle, high, college, university, granduate
}

ex) 열거형 변수의 생성 및 값 변경

var highestEducationLevel: School = School .university
//위와 같은 표현
var highestEducationLevel: School = .university
//같은 타입인 School 내부의 항목으로만 highestEducationLevel의 값을 변경해줄 수 있다.
highestEducationLevel = .primary

2. 원시 값

열거형의 각 항목은 자체로도 하나의 값이지만 항목의 원시 값도 가질 수 있다.
즉, 특정 타입으로 지정된 값을 가질 수 있다는 뜻이다.
원시 값을 사용하려면 rawValue를 사용하면 된다.

ex) 원시 값

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

let highestEducationLevel: School = School.university
print("최종학력은 \(highestEducationLevel.rawValue) 졸업")


enum WeekDays: Character{
    case mon="월", tue="화", wed="수", thu="목", fri="금", sat="토", sun="일"
}
let today: WeekDays = WeekDays.fri
print("오늘은 \(today.rawValue)요일")

일부의 항목만 원시 값을 줄 수 있다.
문자열 형식의 원시 값을 지정했다면 각 항목의 이름을 그대로 원시 값으로 갖게 되고,
원시 값의 형식이 정수라면 첫 항목을 기준으로 0부터 1씩 더한 값을 갖게 된다.
ex) 원시 값 일부 지정

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

let highestEducationLevel: School = School.university
print(highestEducationLevel) //univeersity
print(School.elementary.rawValue) //초등학교

enum Numbers: Int{
    case zero, one, two, ten=10
}

print(Numbers.zero.rawValue)//0
print(Numbers.one.rawValue)//1
print(Numbers.two.rawValue)//2
print(Numbers.ten.rawValue)//10

ex) 원시 값을 통한 열거형 초기화

let primary = School(rawValue: "유치원")//primary
let graduate = School(rawValue: "석박")//nil
let one = Numbers(rawValue: 1)//one
let three = Numbers(rawValue: 3)//nil

3. 연관 값

열거형 내의 항목이 자신과 연관된 값을 가질 수 있다.
연관 값은 각 항목 옆에 소괄호로 묶어 표현할 수 있다.
일부의 항목만 연관 값을 가지게 할 수 있다.

ex) 열거형 - 연관 값

enum Maindish{
    case pasta(taste: String)
    case pizza(dough:String, topping:String)
    case chicken(withSauce: Bool)
    case rice
}

var dinner: Maindish = Maindish.pasta(taste: "크림")
print(dinner) // pasta(taste: "크림")
dinner = .pizza(dough: "리치골드", topping: "포테이토")
dinner = .chicken(withSauce: true)
dinner = .rice

ex) 열거형 응용

enum PastaTaste{
    case cream, tomato
}

enum PizzaDaugh{
    case cheeseCrust, thin, richgold
}

enum PizzaTopping{
    case pepperoni, potato, chicken
}

enum Maindish{
    case pasta(taste: PastaTaste)
    case pizza(dough:PizzaDaugh, topping:PizzaTopping)
    case chicken(withSauce: Bool)
    case rice
}

var dinner: Maindish = Maindish.pasta(taste: PastaTaste.tomato)
dinner = Maindish.pizza(dough: PizzaDaugh.thin, topping: PizzaTopping.potato)

4. 항목 순회

열거형에 포함된 모든 케이스를 알고 싶을 때 CaseIterable을 사용한다.
그러고 나서 allCases를 사용하여 모든 케이스의 컬렉션을 생성할 수 있다.

ex) 항목 순회 - CaseIterable

enum School: CaseIterable{
    case primary
    case elementary
    case middle
    case high
    case college
    case university
}

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

ex) 항목 순회 - 원시 값

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

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

ex) 항목 순회 - available 속성을 갖는 열거형

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 allCases: [School] = School.allCases
print(allCases)

5. 순환 열거형

순환 열거형은 열거형 항목의 연관 값이 열거형 자신의 값이고자 할 때 사용한다.
순환 열거형을 명시하고 싶다면 indirect 키워드를 사용한다.
특정 항목에만 한정하고 싶다면 case 키워드 앞에 indirect을 붙이고, 열거형 전체에 적용하고 싶다면 enum앞에 indirect를 붙인다.

ex) 특정 항목의 순환 열거형 명시

enum ArithmeticExpression{
    case Number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiple(ArithmeticExpression, ArithmeticExpression)
}

ex) 열거형 전체에 순환 열거형 명시

indirect enum ArithmeticExpression{
    case Number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiple(ArithmeticExpression, ArithmeticExpression)
}

ex) 순환 열거형 응용

let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.addition(five, four)
let final = ArithmeticExpression.multiple(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 .multiple(let left, let right): return evaluate(left) * evaluate(right)
    
    }
}

let result: Int = evaluate(final)
print(result)

6. 비교 가능한 열거형

Comparable 프로토콜을 준수하는 연관 값만 갖거나 연관 값이 없는 열거형은 Comparable 프로토콜을 채택하면 각 케이스를 비교할 수 있다. 앞에 위치한 케이스가 더 작은 값이 된다.

ex) 비교 가능한 열거형

enum Condition: Comparable{
    case terrible
    case bad
    case good
    case great
}

let myCondition: Condition = Condition.great
let yourCondotion: Condition = Condition.bad

if myCondition >= yourCondotion{
    print("my condition is better than you")
}else{
    print("your condition is better than me")
}

enum Device: Comparable{
    case iPhone(version: String)
    case iPad(version: String)
    case macBook
    case iMac
}

var devices: [Device] = []
devices.append(Device.iMac)
devices.append(Device.iPhone(version: "14.5"))
devices.append(Device.iPhone(version: "6.1"))
devices.append(Device.iPad(version: "10.2"))
devices.append(Device.macBook)

let sortedDevices: [Device] = devices.sorted()
print(sortedDevices)
profile
호박에 줄 그어서 수박 되는 성장 드라마

0개의 댓글