article thumbnail image
Published 2020. 10. 26. 17:36
728x90
반응형

스위프트에서의 열거형은 다른 언어의 열거형과 많이 다르다고 한다.
열거형은 강력한 기능을 가지고 있어 잘 알아두고 사용하면 좋다고 한다.

- 유사한 종류의 여러 값을 한 곳에 모아서 정의한 것이다. 예) 요일, 월, 계절 등
- enum 자체가 하나의 데이터 타입으로, 대문자 카멜케이스를 사용하여 이름을 정의한다.
- 각 case 는 소문자 카멜케이스로 정의한다.

enum BootCamp { // 대문자 카멜케이스
    case iosCamp // 소문자 카멜케이스
    case androidCamp
    case webCamp
}

- 각 case 는 그 자체가 고유의 값입니다. (각 case에 자동으로 정수값이 할당되지 않음)
- 각 case 는 한 줄에 개별로도, 한 줄에는 여러개도 정의할 수 있습니다.

eum 이름 {
    case 이름1
    case 이름2 // 개별 정의
    case 이름3, 이름4, 이름5 // 다수 정의
}

 

그럼, 열거형을 어떻게 사용할까?

타입이 명확할 경우, 열거형의 이름을 생략할 수 있다.
switch 구문에서 사용하면 좋다.

enum Month {
    case jan
    case feb
    case mar
}

// 열거형 타입과 케이스를 모두 사용하여도 된다.
var whr: Month = Month.jan
print(whr)
// 타입이 명확하다면 .케이스 처럼 표현해도 무방하다.
whr = .mar
print(whr)

// switch 의 비교값에 열거형 타입이 위치할 때
// 모든 열거형 케이스를 포함한다면
// default 를 작성할 필요가 없다.
switch whr {
case .jan, .feb:
    print("겨울입니다.")
case .mar:
    print("봄입니다.")
}

간단하게 Month라는 열거형을 만들어보았다.
변수에 열거형 타입과 케이스를 모두 사용해도 된다. 타입이 명확하다면 .케이스 라고 표현해도 된다.
그리고 열거형 타입일 경우,
switch 의 비교값(위에서 whr)이 열거형 타입이 모든 열거형 케이스를 포함한다면 default 를 작성할 필요가 없다고 한다.

// 열거형 타입과 케이스를 모두 사용하여도 된다.
var whr: Month = Month.jan

이말은 즉, whr 이란 변수를 열거형 타입으로 정해주었고

enum Month {
    case jan
    case feb
    case mar
}

switch whr {
case .jan, .feb:
    print("겨울입니다.")
case .mar:
    print("봄입니다.")
}

switch 구문의 케이스에 열거형 3가지 케이스가 모두 포함되어 있기 때문에 default 가 없어도 된다.
하지만, 하나라도 포함되지 않는다면 아래와 같이 에러가 발생한다.

enum Month {
    case jan
    case feb
    case mar
    case apr
}

에러를 통해 Fix 를 누르면 다음과 같이 case 가 하나 더 생성되는 것을 확인할 수 있었다.


다음으로, rawValue(원시값)에 대해서 알아보자.

- C 언어의 enum 처럼 정수값을 가질 수 있다.
- rawValue 는 case 별로 각각 다른 값을 가져야 한다.
- 자동으로 1이 증가된 값이 할당된다.
- rawValue 를 반드시 지닐 필요가 없다면 굳이 만들지 않아도 된다.

enum Count: Int {
    case one = 1
    case two
    case three
    // one 과 원시값이 같기 때문에 ones 의 원시값을 1로 정의할 수 없다.
    //case ones = 1
}

var cnt: Count = Count.one

print(cnt.rawValue)
cnt = .two
print(cnt.rawValue)
cnt = .three
print(cnt.rawValue)

========== 출력 결과 ==========
1
2
3

간단한 예를 만들어보았다.
자동으로 1씩 증가하는 것을 확인할 수 있었고
case 별로 각 다른 값을 가져야 하기 때문에 중복으로 원시값을 가질 수 없다는 것도 확인할 수 있었다.

정수 뿐만 아니라, Hashable 프로토콜을 따르는 모든 타입을 원시밗의 타입으로 지정할 수 있다.
다음 예를 통해 확인해볼 수 있었다.

enum School: String {
    case elementary = "초등"
    case middle = "중등"
    case high = "고등"
    case university // 원시값 없음
}

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

========== 출력 결과 ==========
중등
university // 원시값을 케이스 이름으로 사용

middle 케이스의 "중등" 이라는 rawValue 라는 값을 갖지만,
university 케이스는 rawValue 의 값이 없기 때문에 case 의 이름을 원시값으로 사용한다.

그리고 원시값을 통해 초기화를 해줄 수 있다.

원시값이 열거형 케이스에 해당하지 않을 수도 있기 때문에 원시값을 통해 초기화한 인스턴스는 옵셔널 타입이다.
다음은 옵셔널 타입으로 해주지 않았을 경우 발생하는 에러다.

따라서, 다음과 같이 옵셔널 타입으로 정해줄 수 있다.

// 원시값을 통해 초기화한 열거형 값은 옵셔널 타입으므로 School 타입이 될 수 없다.
// let Heungduck: School = School(rawValue: "high")
let Heungduck: School? = School(rawValue: "high")

옵셔널에서 공부했었던 if let 구문을 통해서 사용할 수도 있다.

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


// 원시값을 통해 초기화한 열거형 값은 옵셔널 타입으므로 School 타입이 될 수 없다.
// let Heungduck: School = School(rawValue: "high")
let Heungduck: School? = School(rawValue: "고등")

// if let 구문을 사용하면 원시값에 해당하는 케이스를 곧바로 사용할 수 있다.
if let miho: School = School(rawValue: "중등") {
    print("원시값 '중등' 에 해당하는 케이스는 \(miho) 이다")
} else {
    print("middle 에 해당하는 원시값이 없다.")
}

========== 출력 결과 ==========
원시값 '중등' 에 해당하는 케이스는 middle 이다

위와 같이 예를 통해 확인해볼 수 있었다.

마지막으로, 열거형에는 메서드도 추가해서 사용할 수 있다.

enum Job {
    case engineer
    case designer
    case programmer
    case developer
    
    func printMessage() {
        switch self {
        case .engineer:
            print("엔지니어!")
        case .designer:
            print("디자이너!")
        case .programmer:
            print("프로그래머!")
        case .developer:
            print("개발자!")
        // 열거형의 모든 케이스가 포함되어 있기 때문에 default 사용 안함
        }
    }
}

Job.engineer.printMessage()

========== 출력 결과 ==========
엔지니어!

 

정리

열거형에 대해서 알아보았는데 직접적으로 사용해본 적은 없는 것 같다.
그래서 사용법을 익히는데 조금 시간을 더 투자한 것 같다.
열거형은 아주 광범위한 곳에서 사용될 수 있는 자료형이라고 한다.
그리고 열거형은 구조체와 함께 활용하는 것을 권장하고 있다고 한다.
열거형의 특징들을 잘 활용한다면 보다 간결한 코드를 짤 수 있지 않을까 생각한다.

- 참고 사이트 -

www.edwith.org/boostcamp_ios/lecture/11273

 

[LECTURE] 15. 열거형 (💎생각해보기) : edwith

생각해보기   ▶본문 예시의 BoostCamp , Weekday , School , Fruit , Month 는 각각 열거형의 예로 적합한가요? ▶그렇게 생각한 이유는 무엇인가요?... - 부스트코스

www.edwith.org

medium.com/@JinwooChoi/swift에서-열거형-활용하기-aaf69148e08d

 

Swift에서 열거형 활용하기

열거형은 어디서든 사용된다.

medium.com

 

728x90
반응형
복사했습니다!