2025/07/12

7. Swift 열거형(Enum): 관련된 값들을 하나의 타입으로 묶는 방법

Swift 열거형(Enum)
안녕하세요! 지난 블로그에는 여러 데이터를 효율적으로 관리하는 컬렉션 타입인 배열과 딕셔너리에 대해 마스터했습니다. 오늘은 Swift에서 관련된 값들을 그룹화하여 코드의 가독성과 안전성을 높이는 데 사용되는 강력한 타입인 열거형(Enumeration), 줄여서 Enum에 대해 자세히 알아보겠습니다.

열거형은 단순히 값들을 나열하는 것을 넘어, 코드의 실수를 줄이고 의미를 명확하게 전달하는 데 큰 도움을 줍니다. 마치 여러 옵션이 있는 메뉴판처럼, 정해진 선택지 안에서만 값을 선택하도록 강제함으로써 예측 불가능한 상황을 방지하고 코드의 안정성을 높여줍니다.


1. 열거형(Enum)이란 무엇인가요? 

열거형은 관련된 값들의 그룹을 정의하는 사용자 정의 타입입니다. 특정 값의 집합이 유한하고 명확할 때 사용하며, 각 값을 케이스(case)라고 부릅니다.
예를 들어, 나침반의 방향(북, 남, 동, 서), 요일(월, 화, 수...), 비디오 게임의 레벨(쉬움, 보통, 어려움) 등이 열거형으로 표현하기 적합한 값들입니다.

💡 열거형을 사용하는 이유: 

  • 타입 안전성 향상: 미리 정의된 케이스 외의 다른 값을 사용할 수 없도록 하여 오타나 잘못된 값으로 인한 오류를 방지합니다.
  • 코드 가독성 증가: 숫자나 문자열 '매직 넘버' 대신 의미 있는 이름을 사용하여 코드를 훨씬 더 읽기 쉽게 만듭니다.
  • 코드 자동 완성 및 리팩토링 용이: IDE의 도움을 받아 오타 없이 케이스를 선택할 수 있고, 나중에 케이스 이름이 변경되어도 쉽게 리팩토링할 수 있습니다.

1.1. 열거형의 기본 정의 및 사용

열거형은 enum 키워드를 사용하여 정의합니다.

// 방향을 나타내는 열거형 정의
enum CompassPoint {
    case north
    case south
    case east
    case west
}

// 열거형 사용
var directionToHead = CompassPoint.south
print(directionToHead) // 출력: south

// 이미 타입을 추론했으므로 점(.) 표기법으로 축약 가능
directionToHead = .north
print(directionToHead) // 출력: north

2. switch 문과 함께 열거형 활용하기

열거형은 switch 문과 함께 사용될 때 강력한 시너지를 발휘합니다. switch 문은 열거형의 모든 케이스를 효율적으로 처리하고, Swift 컴파일러는 모든 케이스가 처리되었는지 자동으로 검사하여 누락된 케이스가 있을 경우 경고나 오류를 발생시킵니다. 이는 코드의 안정성을 크게 향상시킵니다.
//Swift 예제
enum GameLevel {
    case easy
    case medium
    case hard
    case expert
}

let playerLevel = GameLevel.medium

switch playerLevel {
case .easy:
    print("초보자 모드입니다. 가볍게 즐겨보세요!")
case .medium:
    print("보통 난이도입니다. 적절한 도전을 즐기세요!")
case .hard:
    print("어려움 난이도입니다. 실력을 시험할 때입니다!")
case .expert:
    print("전문가 모드입니다. 당신은 진정한 고수!")
}
// 출력: 보통 난이도입니다. 적절한 도전을 즐기세요!

3. 원시 값(Raw Values): 특정 타입의 값과 연결하기 

열거형의 각 케이스는 특정 타입의 원시 값(Raw Value)을 가질 수 있습니다. 
원시 값은 열거형 정의 시 미리 할당되며, 각 케이스를 고유하게 식별하는 데 사용됩니다. Int, String, Character, Float, Double 타입이 원시 값으로 사용될 수 있습니다. 

💡 원시 값의 특징: 

  • 고유성: 각 케이스의 원시 값은 고유해야 합니다.
  • 자동 할당: Int 원시 값을 사용할 경우, 첫 번째 케이스에 값을 지정하면 다음 케이스부터는 1씩 자동으로 증가합니다. String 원시 값의 경우 케이스 이름이 기본값이 됩니다. 

//Swift 예제

enum HTTPStatusCode: Int { // Int 타입의 원시 값
    case success = 200
    case badRequest = 400
    case unauthorized = 401
    case notFound = 404
    case serverError = 500
}

print(HTTPStatusCode.success.rawValue) // 출력: 200
print(HTTPStatusCode.notFound.rawValue) // 출력: 404

// 원시 값으로 열거형 인스턴스 생성 (옵셔널 반환)
if let status = HTTPStatusCode(rawValue: 200) {
    print("받은 HTTP 상태 코드: \(status)") // 출력: 받은 HTTP 상태 코드: success
} else {
    print("알 수 없는 HTTP 상태 코드입니다.")
}

enum Season: String { // String 타입의 원시 값 (케이스 이름이 기본값)
    case spring
    case summer
    case autumn
    case winter
}

print(Season.summer.rawValue) // 출력: summer

4. 연관 값(Associated Values): 케이스별로 다른 값 저장하기 

열거형의 각 케이스는 하나 이상의 연관 값(Associated Value)을 가질 수 있습니다.
이는 원시 값과는 다르게, 특정 케이스가 선택될 때마다 함께 저장되는 추가 정보입니다. 연관 값은 열거형 정의 시점에 미리 정해지는 것이 아니라, 열거형 인스턴스를 생성할 때 전달됩니다.

💡 연관 값의 특징:

  • 유연성: 각 케이스가 완전히 다른 타입과 개수의 연관 값을 가질 수 있습니다. 
  • 정보 포함: 케이스 자체가 아닌, 그 케이스에 대한 추가적인 상세 정보를 포함할 때 유용합니다. 


//Swift 예제

enum Barcode {
    case upc(Int, Int, Int, Int) // UPC 코드: 숫자 4개
    case qrCode(String)        // QR 코드: 문자열 1개
}

// 연관 값과 함께 열거형 인스턴스 생성
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
var anotherBarcode = Barcode.qrCode("ABCDEFGHIJKLMNOP")

// switch 문을 이용한 연관 값 추출
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check): // 연관 값 바인딩
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}
// 출력: UPC: 8, 85909, 51226, 3.

// 연관 값 바인딩 축약 (let 또는 var를 한 번만 사용)
switch anotherBarcode {
case let .upc(numberSystem, manufacturer, product, check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
    print("QR code: \(productCode).")
}
// 출력: QR code: ABCDEFGHIJKLMNOP.
   

연관 값은 데이터의 종류에 따라 유연하게 추가 정보를 담을 수 있어 매우 강력합니다.

정리하며

오늘은 Swift의 타입 안전성과 가독성을 크게 향상시켜주는 열거형(Enum)에 대해 자세히 알아보았습니다.

  • 열거형: 관련된 값들을 하나의 타입으로 묶는 강력한 도구입니다.
  • switch 문과의 시너지: 모든 케이스를 처리하도록 강제하여 안정성을 높입니다.
  • 원시 값(Raw Values): 각 케이스에 미리 정의된 특정 타입의 값을 연결하여 사용합니다.
  • 연관 값(Associated Values): 각 케이스에 동적으로 추가 정보를 함께 저장할 수 있어 유연성을 제공합니다.

열거형은 Swift 개발에서 정말 자주 사용되는 개념입니다.
특히 네트워크 통신 응답 처리, UI 상태 관리 등 다양한 상황에서 빛을 발합니다.
오늘 배운 내용을 바탕으로 여러분의 코드에 열거형을 적극적으로 활용해 보세요!

0 comments:

댓글 쓰기