이놈(enum).... 이놈의 자식 넌 누구냐

BS_Lee·2025년 6월 25일

swift

목록 보기
9/21

1. enum이란?

enum은 한정된 값의 집합을 표현하는 타입이다.
예를 들어, 동물의 종류처럼 "정해진 선택지"를 다룰 때 쓰기 좋다.

enum Animals {
    case cat
    case dog
    case rabbit
}

이렇게 Animals.cat처럼 쓰면, 이것 자체가 enum 타입의 값이 된다.
출력하면 "cat"처럼 보일 수도 있지만, 실제로는 문자열이 아니다.

그럼 여기서 궁금한 게 하나 생긴다.

문자열처럼 출력하고 싶으면 어떻게 하지?

그럴 땐 RawRepresentable을 활용하면 된다.
뒤에 붙는거는 프로토콜인데 이건 스웨덴 형님이 나중에 알려주신다고 참고만 하시란다.
(지금은 클로저 후유증이 좀 남아있으니 더 안파고 넘어가보겠다.)

enum Animals: String {
    case cat, dog, rabbit
}

print(Animals.cat.rawValue)  // "cat"

2. enum을 언제 쓸까?

정해진 상태나 선택지를 표현하고 싶을 때 enum이 제격이다.

예를 들어:

  • 로그인 상태: .loggedIn, .loggedOut
  • 네트워크 상태: .loading, .success(data), .failure(error)
  • 방향: .left, .right

왜 좋냐면
switch문과 찰떡이고, 연관 값을 붙여서 다양한 상태를 안전하게 표현할 수 있기 때문이다.


3. enum에서 == 비교가 안 되는 이유는?

enum Shortcut {
    case fileOrFolder(path: URL, name: String)
    case wwwUrl(path: URL)
}

let a = Shortcut.wwwUrl(path: URL(string: "https://apple.com")!)

if a == Shortcut.wwwUrl(path: URL(string: "https://apple.com")!) {
    // Error 발생
}

왜 안 될까?

바로, 연관 값이 있는 enum은 자동으로 Equatable을 채택하지 않기 때문이다.

해결 방법:

enum Shortcut: Equatable {
    case fileOrFolder(path: URL, name: String)
    case wwwUrl(path: URL)
}

4. 그럼 switch는 왜 잘 작동할까?

switch a {
case .wwwUrl(let path):
    print(path)
default:
    break
}

switch패턴 매칭 기반이라, Equatable이 없어도 내부 case 구조를 직접 분해해서 비교한다.
즉, == 연산이 아니라 구조 자체를 비교하는 방식이다.
==는 값을 비교하는거라고 한다면 switch같은 경우에는, 값이 특정 구조, 모양, 조건을 만족하는지 검사하는 방식


5. if case let 문법

if case let .wwwUrl(path) = a {
    print(path)
}

// 이거랑 똑같다고 보면 된다
switch a {
	case let .wwwUrl(path):
    	print(path)
    	break
    defualt:
    	"somthing else..."
}

이건 switch를 줄여 쓴 문법이다.
특정 케이스만 확인하고, 연관 값도 꺼내고 싶을 때 아주 편리하다.

비슷하게 guard case, for case, while case도 쓸 수 있다.


6. 재귀 enum이란? indirect?

이게 조금 난이도 있는 부분이다.

indirect enum IntOperation {
    case add(Int, Int)
    case subtract(Int, Int)
    case freeHand(IntOperation)
}

여기서 freeHand는 다시 IntOperation을 포함하고 있다.
이건 재귀 구조인데, Swift의 enum은 값 타입이라 스스로를 가질 수 없다.
그래서 indirect 키워드를 써서 힙에 저장되도록 한다.


7. 재귀 enum을 이용한 계산 예제

indirect enum IntOperation {
    case add(Int, Int)
    case subtract(Int, Int)
    case freeHand(IntOperation)
    
    func calculateResult(
        of operation: IntOperation? = nil
    ) -> Int {
        switch operation ?? self {
        case let .add(lhs, rhs):
            return lhs + rhs
        case let .subtract(lhs, rhs):
            return lhs + rhs
        case let .freeHand(operation):
            return calculateResult(of: operation)
        }
    }
}

여기서 핵심은 operation ?? self다.
함수 호출 시 매개변수가 없으면 self를 쓰는 구조다.
즉, 이런 식으로도 가능하다:

let freeHand = IntOperation.freeHand(.add(20, 30))
freeHand.calculateResult()  // 50

8. 그럼 struct와의 차이는 뭐야?

항목structenum
목적여러 속성을 가진 데이터 구조 표현상태나 선택지를 표현
구성여러 프로퍼티 가능한 번에 하나의 case만 존재
연관값없음 (모든 속성이 고정 필드로 존재)특정 case에만 연관값 가능
switch 사용(switch, if case 등 패턴 매칭 가능)
상속

한 줄 정리

enum은 상태를 표현하고,
struct는 데이터를 담는다.

0개의 댓글