어떤 입력 값을 사전에 입력해놓고 그 값만 이용하고 싶다면 enum을 사용하면 된다. 사전에 정의를 해놓기때문에 오탈자도 방지할 수 있고 Stack에 저장되기 때문에 성능이 향상된다.
클래스를 붕어빵 틀에 비유하고 인스턴스를 붕어빵에 비유하는데, 여기서 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이 출력된다.
enum은 rawValue를 지정해줄 수 있다. 지정해줄 수 있는 타입은 Number Type, Character Type, String Type 세가지가 가능하다.
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로 가질 것이다.
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가 되는 것이 아니라 에러가 발생한다.
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는 반드시 rawValue를 지정해줘야한다. 하나라도 없으면 에러가 발생한다.
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를 이용해야하니 이건 다음 기회에 알아봐야겠다.
https://babbab2.tistory.com/116
https://0urtrees.tistory.com/197