Apple/Swift

[iOS/Swift] 열거형(Enums) 이란?

59date 2024. 7. 20. 19:27

열거형이란?

연관된 값들을 모아 하나의 이름으로 묶은 타입을 열거형이라고 부릅니다.

열거형에 포함된 변수 혹은 상수는 이름 그대로 부르지 않고 케이스(case)라고 부릅니다.

 

열거형을 사용하는 이유는 다음과 같습니다.

  1. 코드의 가독성 향상
  2. 타입 안전성 보장
  3. 제한적인 값 집합 표현
  4. 메모리 효율성

먼저 열거형의 기본 구조를 살펴봅시다.

enum 열거형_이름 {
    case 케이스1
    case 케이스2
    case 케이스3
    case 케이스4, 케이스5, 케이스6
    // 추가적인 케이스들...
}

 

  • enum 키워드를 사용하여 열거형을 정의합니다.
  • 열거형_이름은 열거형의 이름을 지정합니다.
  • case 키워드를 사용하여 열거형의 개별 케이스를 정의합니다.
  • 각 케이스는 case 키워드 뒤에 고유한 이름을 가집니다.
  • 여러 개의 케이스를 한 줄에 정의할 수도 있습니다. 

 

요일을 나타내는 열거형을 정의해 보자면

enum Weekday {
    case monday
    case tuesday
    case wednesday
    case thursday
    case friday, saturday, sunday
}

 

이렇게 정의할 수 있고 열거형 Weekday는 7개의 케이스를 가지게 됩니다.

 

 

만약 열거형을 사용하지 않고 Weekday를 나타낸다면

let monday = 0
let tuesday = 1
let wednesday = 2
let thursday = 3
let friday = 4
let saturday = 5
let sunday = 6
let mondayString = "Monday"
let tuesdayString = "Tuesday"
let wednesdayString = "Wednesday"
let thursdayString = "Thursday"
let fridayString = "Friday"
let saturdayString = "Saturday"
let sundayString = "Sunday"

 

두 코드처럼 나타낼 수 있습니다. 열거형을 사용하지 않아도 Weekday를 나타낼 수 있지만 앞서 말했듯이 열거형을 사용하면 타입 안전성, 가독성 향상 등 여러 장점이 존재합니다.

 

열거형 비교

열거형은 Equatable 프로토콜을 준수하기 때문에, 기본적인 비교 연산자(==, !=)를 사용할 수 있습니다.

열거형 Weekday를 활용하여 열거형을 비교해보면

enum WeekDay {
    case monday, tuesday, wednesday, thursday, friday, saturday, sunday
}

let today: WeekDay = .monday
let tomorrow: WeekDay = .tuesday

if today == .monday {
    print("Today is Monday.")
}

if today != tomorrow {
    print("Today is not the same as tomorrow.")
}
  • enum Weekday { . . . } - Weekday라는 요일을 나타내는 열거형을 정의합니다. Weekday는 7개의 케이스를 가지고 있습니다.
  • let today: Week day = .monday today - today 상수를 선언하고, 이를 Weekday 열거형의 .monday 케이스로 초기화합니다.
  • let tomorrow: Weekday = .tuesday - 위 설명과 동일하게 today 상수 선언 후 ,tuesday 케이스로 초기화합니다.
  • if today == .monday { print("Today is Monday.") } - today 변수가 .monday 케이스와 동일한지 비교합니다. 동일하다면 "Today is Monday."를 출력합니다.
  • if today != tomorrow { print("Today is not the same as tomorrow.") } - today 변수가 tomorrow 변수와 다른지 비교합니다. 다르다면 "Today is not the same as tomorrow."를 출력합니다.

 

열거형 처리

열거형을 처리하는 방법에는 여러 가지가 존재하지만 가장 깔끔한 처리 방법인 switch문을 활용해 보겠습니다.

switch 문을 사용하면 열거형의 모든 케이스를 명시적으로 다룰 수 있어 코드의 가독성과 안정성이 높아집니다. 또한 모든 케이스를 다루지 않으면 컴파일러가 경고를 발생시켜 누락된 부분을 쉽게 찾을 수 있습니다.

 

Weekday 열거형의 값에 따라 해당 요일의 메시지를 출력하는 간단한 switch문 예제입니다.

enum Weekday {
    case monday
    case tuesday
    case wednesday
    case thursday
    case friday, saturday, sunday
}

let today: Weekday = .friday

switch today {
case .monday:
    print("오늘은 월요일입니다.")
case .tuesday:
    print("오늘은 화요일입니다.")
case .wednesday:
    print("오늘은 수요일입니다.")
case .thursday:
    print("오늘은 목요일입니다.")
case .friday:
    print("오늘은 금요일입니다.")
case .saturday:
    print("오늘은 토요일입니다.")
case .sunday:
    print("오늘은 일요일입니다.")
}

코드를 간단하게 설명해 보자면.

  • Weekday 열거형을 정의합니다. 7개의 case개 존재합니다.
  • today 상수를 .friday로 지정합니다.
  • today 상수 값이 따른 switch문을 실행합니다.
  • 각 case에 해당하는 요일 메시지를 출력합니다.
  • today가 .friday이므로 "오늘은 금요일입니다."를 출력하게 됩니다.

 

원시 값(Raw Values)

열거형에서 각 case에 대해 기본적으로 제공되는 값을 의미합니다. 각 case는 기본적으로 정수 값으로 표현되지만, 필요에 따라 다른 데이터 타입의 원시 값(Raw Values)를 지정할 수 있습니다. 이러한 원시 값은 각 case를 고유하게 식별할 수 있게 해 줍니다.

 

간단한 예제를 확인해 보겠습니다.

enum Weekday: Int {
    case monday = 1
    case tuesday
    case wednesday
    case thursday
    case friday, saturday, sunday
}

print(Weekday.wednesday.rawValue) //3

 

  • Weekday라는 열거형을 정의하고, 그 열거형의 원시 값 타입을 Int로 지정해줍니다.
  • monday case의 원시 값을 1로 지정했습니다
    • 만약 따로 지정을 하지 않는다면 자동적으로 0부터 시작하게 됩니다.
  • monday가 1이므로 tuesday는 자동으로 2가 됩니다.
    • 따로 지정을 하지 않아 0부터 시작하게 된다면 tuesday는 1이 됩니다.
  • 나머지는 각각 3,4,5,6,7이 되게 됩니다.
  • wednesday의 원시 값을 출력하게 되면 3이 출력됩니다.

 

만약

enum Weekday: Int {
    case monday
    case tuesday = 10
    case wednesday
    case thursday
    case friday, saturday, sunday
}

print(Weekday.monday.rawValue) //0
print(Weekday.tuesday.rawValue) //10
print(Weekday.wednesday.rawValue) //11

 

tuesday에 원시값을 저장하게 된다면 세 번째 case에 저장된 값은 2가 아니라 11이 나오게 됩니다.

하지만 monday의 원시 값은 9가 아니라 0이 출력됩니다.

즉 원시 값을 직접 저장하게 된다면 이전 case에 원시 값은 증가하지 않게 됩니다.

 


 

잘못된 내용 혹은 오타가 있거나 더 좋은 내용 피드백은 언제나 환영입니다 :)