본문 바로가기
etc/Swift

열거형(enum)

by IT learning 2021. 5. 24.
728x90

스위프트의 열거형은 다른 언어의 열거형과는 다르게굉장히 강력한 기능을 가지고 있다. 

따라서 많이 알고 있으면 스위프트 언어를 할때 이득이 많이 될 것이다.

enum 이름 {
    case 이름1
    case 이름2
    case 이름3,이름4,이름5
    ...
}

열거형의 각 case는 고유의 값으로 취급이 된다. C의 열거형에서는 케이스별로 정수형이 자동으로 취급됐던것과는 다른 것이다.

 

열거형 사용

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


var day: Weekday = Weekday.mon  // 열거형의 케이스를 나타내는 문법은 열거형.타입이름
day = .fri                      // 축약도 가능, 근데 처음에 선언을 애매하게 해주면 축약 불가능

print(day)

// 스위치의 비교값에 day라는 열거형 값이 들어가 있기 때문에 케이스는 한정적이라고 컴파일러는 알 수 있다.
// 그래서 케이스를 축약해서 사용이 가능하다.
switch day {
case .mon, .tue, .wed, .thu:
    print("평일입니다.")
case Weekday.fri:
    print("불금!")
case .sat, .sun:
    print("신나는 주말")
}

열거형의 케이스에는 하나도 설정이 가능하지만, 여러개도 설정이 가능하다.

 

열거형을 사용하는 법은 열거형.타입이름 으로 사용이 가능하고,

다른 변수에 값을 옮길때, 먼저 선언이 되어있으면 축약해서 사용도 가능하다.

 

그리고 열거형은 switch에서 사용이 가능하다. 오히려 유용하다.

 

switch의 비교가뵤에 day를 넣어 열거형 값이 들어간다고 인지 시키면 컴파일러는 '열거형이 들어갔으니 축약 쌉가능이네 아 ㅋㅋ'가 가능하다. 그래서 스위치 문에 여러 케이스를 보면 축약을 해놓은 상태이다.

 

원시값

enum Fruit: Int {   // 열거형의 이름 뒤에 타입을 명시해주면 된다.
    case apple = 0
    case grape = 1  // C처럼 자동으로 1씩 늘어난다. 그래서 저 1을 지워도 1로 할당이 된다.
    case peach      // 얘는 그럼 2
//  case mango = 0
}

print("Fruit.peach.rawValue == \(Fruit.peach.rawValue)") //꺼내올때는 기존에 스위프트에서 사용하는 방법처럼 사용이 가능하다.
// Fruit.peach.rawValue == 2

C언어의 열거형 처럼 원시값을 넣을수도 있다. 사용하는 방법은 기존의 열거형의 이름 뒤에 타입을 명시해주고 사용하면 된다.

각 케이스에 이름과 수를 넣어주면 되는데, 수를 넣지 않아도 순서대로 0,1,2,3... 이 알아서 기입이된다.

case별로 각각 다른 값을 가져야 한다.

출력하거나 꺼내오는 방법은 기존의 스위프트 출력문과 동일하다.

 

enum School: String {
    case elementary = "초등"
    case middle = "중등"
    case high = "고등"
    case university // 문자열의 경우에는 0,1,2,3 뭐 이렇게 늘어나는게 아니니까, 케이스의 이름 그대로 rawValue에 들어간다.
}


print("Schaool.middle.rawValue == \(School.middle.rawValue)")
// School.middle.rawValue == 중등

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

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

위 코드는 School 열거형이고 각 케이스는 String 형식의 문자열들이다.

그리고 정수 타입의 열거형은 0,1,2,3.. 이렇게 수가 늘어나고 자동으로 들어간다고 했다. 하지만  String 형식은 숫자처럼 이어진게 아니지 않은가? 그럼 어떻게 될까?  답은 선언된 케이스 이름 그대로 rawValue에 들어간다.

 

출력은 위와 같다.

 

원시값을 통한 초기화

// let apple: Friut = Fruit(rawValue: 0) // 기본으로 했을 경우엔 아래와 같은 예상이 불가능하기 때문에 컴파일러에서 에러를 낸다.
let apple: Fruit? = Fruit(rawValue: 0) // 만약 케이스가 없을 경우에 nil이 나올것을 예상할 수 있게 옵셔널을 사용해야 한다.

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

rawValue를 통해 초기화가 가능하다.

그러나, rawValue가 우리가 선언했던 case에 존재하지 않을수도 있기 때문에, nil이 나오는 것을 예상할 수 있는 옵셔널을 사용하여 초기화 해야한다. 아니면 애초에 에러가 난다.

 

그리고 if let 구문으로 이용이 가능하다.

 

메서드

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("따듯한 봄")
        case .jun, .jul, .aug:
            print("더운 여름")
        case .sep, .oct, .nov:
            print("선선한 가을")
        case .dec, .jan, .feb:
            print("추운 겨울")
        }
    }
}


Month.sep.printMessage()

열거형 안에 메서드를 선언해 사용할 수 있다.

위 코드는 각 달을 케이스로 선언하고, printMessage() 메서드를 이용해 선택된 케이스가 어떤 계절인지를 알려주는 코드이다.

코드에서 .sep이 선택되고 출력을 했을 때 메서드가 호출이 되 '선선한 가을'이 출력이 된다.

728x90

'etc > Swift' 카테고리의 다른 글

클로저  (0) 2021.05.24
클래스 vs 구조체 / 열거형  (0) 2021.05.24
클래스  (0) 2021.05.21
구조체  (0) 2021.05.21
옵셔널(Optional)  (0) 2021.05.17

댓글

IT_learning's Commit