[Swift] Enumeration(열거형)

Page·2022년 5월 19일

Swift

목록 보기
4/6

열거형의 사용

어떤 입력 값을 사전에 입력해놓고 그 값만 이용하고 싶다면 enum을 사용하면 된다. 사전에 정의를 해놓기때문에 오탈자도 방지할 수 있고 Stack에 저장되기 때문에 성능이 향상된다.

클래스를 붕어빵 틀에 비유하고 인스턴스를 붕어빵에 비유하는데, 여기서 enum이 끼어들면 붕어빵의 종류라고 비유할 수 있겠다. 팥 붕어빵을 만들지 슈크림 붕어빵을 만들지 그 종류를 enum에 묶어서 사전에 정의한다.

열거형을 적절하게 사용해서 코드의 가독성과 안정성을 향상 시키자.

enum

enum EPL {
    case tottenham
    case leicester
    case manchesterCity
    case arsenal
}

위의 코드가 rawValue가 없는 enum 사용법이다. 간단히 출력을 해보자.

var team: EPL = .arsenal
print(team)

team = .leicester
print(team)
print(type(of:team))

team에 넣어준 case가 출력된다. 마지막에는 team 변수가 어떤 타입인지 확인해봤다. 문자열이 출력되니까 혹시 String일까해서 확인해봤는데 type은 처음에 지정해준 EPL이 출력된다.

rawValue

enum은 rawValue를 지정해줄 수 있다. 지정해줄 수 있는 타입은 Number Type, Character Type, String Type 세가지가 가능하다.

Int

enum EPL: Int {
    case tottenham = 10
    case leicester = 20
    case manchesterCity = 30
    case arsenal = 40
}

var team: EPL = .arsenal
print(team)
print(team.rawValue)


var team2: EPL = .leicester
print(team2)
print(team2.rawValue)

Int 타입을 rawValue로 지정해준 예제다. team값은 기본적인 case값인 것은 동일하고 .rawValue를 이용해서 rawValue값을 가져올 수 있다.

case와 rawValue를 출력해봤다.

위 이미지는 rawValue를 만들기 전에 EPL 타입에 접근한 경우다. 혹시 자동으로 생성될까해서 확인해본 결과 rawValue를 명시해주지 않으면 접근할 수 없다.

enum EPL: Int {
    case tottenham
    case leicester
    case manchesterCity
    case arsenal
}

Int타입의 경우에는 rawValue로 지정해줬다면 굳이 값을 넣어주지 않아도 자동으로 지정된다. 바로 위 케이스의 rawValue + 1값이 지정되며 tottenham부터 0값이 저장된다.

저장된 값을 확인한 결과. 만약 manchesterCity의 값이 275였다면 arsenal은 1 추가된 276을 rawVallue로 가질 것이다.

Double

enum EPL: Double {
    case tottenham
    case leicester
    case manchesterCity = 10
    case arsenal
}

var team1: EPL = .tottenham
print(team1)
print(team1.rawValue)


var team2: EPL = .leicester
print(team2)
print(team2.rawValue)

var team3: EPL = .manchesterCity
print(team3)
print(team3.rawValue)

var team4: EPL = .arsenal
print(team4)
print(team4.rawValue)

Double형의 경우에는 조금 다르게 동작한다.

지정해준 rawValue 값들이 모두 Int타입이라면 문제가 발생하지 않는다.

enum EPL: Double {
    case tottenham
    case leicester
    case manchesterCity = 11.56
    case arsenal
}

이전 값이 정수라면 Int와 동일하게 동작하지만 이전 값이 실수일 경우 +1을 더한 12.56이 rawValue가 되는 것이 아니라 에러가 발생한다.

String

enum EPL: String {
    case tottenham = "Harry Kane"
    case leicester = "Jaime Vardy"
    case manchesterCity
    case arsenal
}

var team1: EPL = .tottenham
print("\(team1) : \(team1.rawValue)")


var team2: EPL = .leicester
print("\(team2) : \(team2.rawValue)")

var team3: EPL = .manchesterCity
print("\(team3) : \(team3.rawValue)")

var team4: EPL = .arsenal
print("\(team4) : \(team4.rawValue)")

String은 명시적으로 rawValue를 지정해주지 않아도 된다. Int형처럼 +1이 가능한 것은 아니지만 rawValue가 없는 경우에는 case 값이 rawValue가 된다.

Character

Character는 반드시 rawValue를 지정해줘야한다. 하나라도 없으면 에러가 발생한다.

Protocol: CaseIterable

enum을 배열처럼 다루고 싶으면 CaseIterable 프로토콜을 이용한다. ForEach문으로 enum을 순회하거나 전체 Case의 개수를 알고싶은 경우, Case를 삭제하거나 추가하고 싶은 경우. 이런 모든 상황에 CaseIterable을 이용하면 된다.

enum EPL: String, CaseIterable {
    case tottenham = "Harry Kane"
    case leicester = "Jaime Vardy"
    case manchesterCity
    case arsenal
}

CaseIterable을 이용해보자.

EPL Type에 dot operation으로 접근한 결과 allCases 메소드와 AllCases associatedType이 생겼다. 일단 allCases만 실습해보자.

allCases는 static method로 생성해준 instance가 아니라 타입 자체에서 접근 가능하다.

사용할 수 있는 메소드는 너무 많아서 몇가지만 이용해보자.

EPL.allCases.forEach { epl in
    print(epl)
}

클로저를 사용하여 EPL의 모든 케이스를 순회하면서 case 값을 출력했다.
기본적으로 enum은 배열이 아니기때문에 모든 case를 출력하는 것이 불가능한데 CaseIterable을 이용하면 이런게 가능하다.

print(EPL.allCases.count)

이 메소드를 이용하면 전체 케이스 값인 4가 출력된다.
append를 사용하려면 AllCases를 이용해야하니 이건 다음 기회에 알아봐야겠다.

Reference

https://babbab2.tistory.com/116
https://0urtrees.tistory.com/197

0개의 댓글