- 제한된 선택지를 주고 싶을 떄
- 정해진 값 외에는 입력받고 싶지 않을 때
- 예상된 입력 값이 한정되어 있을 때
각 열거형이 고유의 타입으로 인정이 됩니다.
원시값 (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
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
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
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)
순환 열거형은 연관 값이 열거형 자신의 값이고자 할 때, 사용합니다.
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)