[Swift] (기초) Enum / 열거형

2021. 7. 16. 23:42🍏/Swift 기초 공부

열거형 (Enumerations)

열거형은 관련된 값으로 이루어진 그룹을 공통의 형으로(type) 선언해 형 안전성(type-safety)을 보장하는 방법으로 코드를 다룰 수 있게 해줍니다. C나 Objective-C가 Integer값들로 열거형을 구성한 것에 반해 Swift에서는 case값이 string, character, integer, floting 값들을 사용할 수 있습니다. 열거형은 1급 클래스 형(first-class types)이어서 계산된 프로퍼티(computed properties)를 제공하거나 초기화를 지정하거나, 초기 선언을 확장해 사용할 수 있습니다

열거형의 데이터 멤버들은 '정의(Definition)' 개념으로 작성되는 것 이므로 타입으로 사용할 수 있을 뿐만 아니라 컴파일러가 미리 인지할 수도 있습니다. 컴파일러가 미리 인지할 수 있고 없고의 차이는 런타임(Run-Time)오류와 컴파일(Compile) 오류의 차이로 나타납니다. 즉, 열거형을 이용하여 데이터 타입을 정의하고 사용하면 오타나 실수가 발생했을 때 그 즉시 컴파일러가 오류를 찾아줌.

다음 조건이 만족하면 열거형쓰는 것을 추천
1.원치 않는 값이 잘못 입력되는 것을 막고 싶을 때
2.입력받을 값을 미리 특정할 수 있을 때
3.제한된 값 중에서만 선택할 수 있도록 강제하고 싶을 때

열거형으로 정의할 수 있는 데이터 집합의 예시
성별  남, 여, 히즈라
국가  한국, 미국, 일본, 캐나다, 영국 등
지역  서울, 부산, 강원, 충남, 제주 등
직급  사원, 대리, 과장, 차장, 부장 등
색상  빨강, 초록, 파랑
방향  동, 서, 남, 북

각 case는 소문자 카멜케이스로 정의합니다
각 case는 그 자체가 고유의 값입니다.

//MARK: - 열거형 사용

enum Weekday {
    case mon
    case tue
    case wed
    case thu, fri, sat, sun
}

var day: Weekday = Weekday.mon
day = .tue
print(day)

day = Weekday.sun
print(day)


switch day {
case .mon, .tue, .wed, .thu:
    print("평일입니다")
case Weekday.fri:
    print("금요일!")
case .sat:
    print("토요일")
default:
    print("일요일")
}

 

더보기

C언어의 enum처럼 정수값을 가질 수 도 있습니다.
rawValue를 사용하면 가능
case별로 각각 다른 값을 가짐

//MARK: - 원시값

enum Fruit: Int {
    case apple = 0
    case grape = 1
    case peach
    // case mango = 0
}

print("Fruit.peach.rawValue == \(Fruit.peach.rawValue)")

// 정수 타입 뿐만 아니라
// Hashable 프로토콜을 따르는 모든 타입이 원시값의 타입으로 지정될 수 있습니다

enum School: String{
    case elementary = "초등"
    case middle = "중등"
    case high = "고등"
    case university
}

print("School.middle.rawValue == \(School.middle.rawValue)")

print("School.university.rawValue == \(School.university.rawValue)")

 

더보기

rawValue를 통해 초기화 가능
rawValue가 case에 해당하지 않을 수 있으므로
rawValue를 통해 초기화 한 인스턴스는 옵셔널 타입

//MARK: - 원시값

enum Fruit: Int {
    case apple = 0
    case grape = 1
    case peach
    // case mango = 0
}

//let apple: Fruit = Fruit(rawValue: 0)
let apple: Fruit? = Fruit(rawValue: 0)

if let orange: Fruit = Fruit(rawValue: 5) {
    print("rawValue 5에 해당하는 케이스는 \(orange)입니다")
} else {
    print("rawValue 5에 해당하는 케이스는 없습니다.")
}

 

더보기
//MARK: - 메서드

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("spring")
        case .jun, .jul, .aug:
            print("summer")
        case .sep, .oct, .nov:
            print("fall")
        default:
            print("winter")
        }
    }
}

month.mar.printMessage()
month.feb.printMessage()

 

더보기
// 열거형을 사용한 비트마스킹 구현
enum Schedule: UInt, CaseIterable {
	case monday = 0b0000001
	case tuesday = 0b0000010
	case wednesday = 0b0000100
	case thursday = 0b0001000
	case friday = 0b0010000
	case saturday = 0b0100000
	case sunday = 0b1000000
	
	var string: String {
		switch self {
		case .monday: return "월요일"
		case .tuesday: return "화요일"
		case .wednesday: return "수요일"
		case .thursday: return "목요일"
		case .friday: return "금요일"
		case .saturday: return "토요일"
		case .sunday: return "일요일"
		}
	}
}

print(Schedule.monday.rawValue)	// 1
print(Schedule.tuesday.rawValue)	// 2
print(Schedule.wednesday.rawValue)	// 4
print(Schedule.thursday.rawValue)	// 8
print(Schedule.friday.rawValue)	// 16
print(Schedule.saturday.rawValue)	// 32
print(Schedule.sunday.rawValue)	// 64

let workClosed = Schedule.saturday.rawValue | Schedule.sunday.rawValue
let hospitalReservation = Schedule.wednesday.rawValue | Schedule.saturday.rawValue | Schedule.sunday.rawValue   // 수요일 병원 예약
let holidayReport = (hospitalReservation | workClosed) - workClosed
let noWorkDays = workClosed | hospitalReservation

for week in Schedule.allCases {
	if (holidayReport & week.rawValue) > 0 {
		print("\(week.string)에는 연차를 사용합니다.")
	}
	
	if (noWorkDays & week.rawValue) > 0 {
		print("\(week.string)에는 일하지 않습니다.")
	}
}