programming/Swift
[Swift/iOS] 열거형(1)
마들브라더
2022. 10. 8. 21:24
열거형
- 추가/수정이 불가능
- 제한된 선택지를 주고 싶을 때
- 정해진 값 외에는 입력받고 싶지 않을 때
- 예상된 입력 값이 한정되어 있을 때
- 값을 가질 수도 가지지 않을 수도 있음
- 각 항목이 그 자체로 고유의 값이 될 수 있음
- 원시값(raw value) 형태로 실제 값을 가질 수 도 있음
- 연관 값(associated values)을 사용하여 공용체라고 불리는 값의 묶음도 구현 가능
기본 열거형
- 열거형의 선언, 할당, 변경
enum School {
case primary
case elementary
case middle
case high
case college
case university
case graduate
}
enum car {
case bus, taxi, car, truck
}
// 값 할당하고 변경하기
var highestEducationLevel: School = School.university
highestEducationLevel = .university
highestEducationLevel = .graduate // 같은 타입의 내부 항목으로만 변경 가능
원시값
- 각 항목은 자체로도 하나의 값이지만 원시 값도 가질 수 있음(raw value)
- 특정 타입으로 지정된 값을 가질 수 있음
- rawValue라는 프로퍼티를 통해 가져올 수 있음
enum School: String {
case primary = "유치원"
case elementary = "초등학교"
case middle = "중학교"
case high = "고등학교"
case college = "대학"
case university // 원시값은 university
case graduate // 원시값은 graduate
}
enum WeekDays: Character {
case mon = "월", tue = "화", wed = "수", thu = "목", fri = "금", sat = "토", sun = "일"
}
enum Number: Int {
case zero // 0
case one = 1
case two = 2
case three // 3
case ten = 10
case eleven // 11
}
// 원시 값을 안다면 원시 값을 통해 열거형의 변수 또는 상수를 생성해줄 수 있음
// 올바르지 않은 원시값이면 nil 반환
let primary = School(rawValue: "유치원") // primary
print(primary) // Optional(__lldb_expr_17.School.primary)
let graduate = School(rawValue: "석박사") // nil
연관 값
- 열거형 내의 항목(case)이 자신과 연관된 값을 가질 수 있음
- 각 항목 옆에 소괄호로 묶어서 표현
enum MainDish {
case pasta(taste: String)
case pizza(dough: String, topping: String)
case chicken(withSauce: Bool)
case rice
}
var dinner: MainDish = .pasta(taste: "크림")
dinner = .pizza(dough: "치즈크러스트", topping: "불고기")
dinner = .chicken(withSauce: true)
dinner = .rice
- 여러 열거형의 응용
enum PastTaste {
case cream, tomato
}
enum PizzaDough {
case cheeseCrust, thin, original
}
enum PizzaTopping {
case pepperoni, cheese, bacon
}
enum MainDish {
case pasta(taste: PastTaste)
case pizza(dough: PizzaDough, topping: PizzaTopping)
case chicken(withSauce: Bool)
case rice
}
var dinner: MainDish = .pasta(taste: .tomato)
항목 순회
- CaseIterable 프로토콜을 채택, allCases라는 타입 프로퍼티를 통해 모든 케이스의 컬렉션을 생성가능
enum School: CaseIterable {
case primary
case elementary
case middle
case high
case college
case university
case graduate
}
let allCases = School.allCases
print(allCases) // [__lldb_expr_21.School.primary, __lldb_expr_21.School.elementary, __lldb_expr_21.School.middle, __lldb_expr_21.School.high, __lldb_expr_21.School.college, __lldb_expr_21.School.university, __lldb_expr_21.School.graduate]
- 원시값을 닺는 열거형의 항목 순회
enum School: String, CaseIterable {
case primary = "유치원"
case elementary = "초등학교"
case middle = "중학교"
case high = "고등학교"
case college = "대학"
case university = "대학교"
case graduate = "대학원"
}
let allCases = School.allCases
print(allCases) // [__lldb_expr_24.School.primary, __lldb_expr_24.School.elementary, __lldb_expr_24.School.middle, __lldb_expr_24.School.high, __lldb_expr_24.School.college, __lldb_expr_24.School.university, __lldb_expr_24.School.graduate]
- CaseIterable 프로토콜을 채택하는 것만으로는 allCases를 사용할 수 없는 경우
- 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) // 실행환경에 따라 다른 결과
- 연관 값을 갖는 경우에도 CaseIterable 채택 만으로 allCases 사용불가능