enum은 서로 관련된 값을 위한 1급 타입이다. 원시값을 넣어주지 않아도 되며 타입의 하나이기 때문에 대문자로 이름을 시작한다.
enum Dormitory {
case first
case second //각각의 case를 따로 표현 가능
case third, forth //","를 통해 한 번에 나타낼 수 있음
}
var myDormitory: Dormitory = .first //하나의 타입처럼 사용 가능함
var yourDormitory = Dormitory.second //따라서 타입 추론 또한 가능
func changeDormitory() {
myDormitory = .third //이미 Dormitody로 타입이 정해져있어 간단하게 .을 통해 가능한 case를 나타내고 설정 가능
}
switch문을 통해서 코드와 각 case를 매칭시킬 수 있으며 일반적인 switch의 사용법처럼 모든 case에 대한 코드가 정해져있어야 하고 원하는 case 외에는 default로 처리해야 한다.
switch myDormitory { //switch문을 통해 열거형의 각 case에 따라 매칭 가능
case .first :
print("Gryffindor")
case .second :
print("Slytherin")
case .third :
print("Ravenclaw")
case .forth :
print("Hufflepuff") //Dormitory라는 타입의 모든 가능한 값을 지정했기 때문에 default가 없어도 됨. 만약 일부가 생략된 경우는 반드시 default가 포함되어야 함
}
만약 enum의 모든 case에 대한 접근이 필요한 경우 열거형의 이름 옆에 CaseIterable을 붙여 배열처럼 for-in이나 ForEach문에 사용가능하다.
모든 case가 일관된 type으로 하나의 값을 가지면(필요조건) 원시값(RawValue)을 지정해줄 수 있다. 원시값의 타입으로는 정수, 부동소수점숫자, 문자, 문자열이 가능하다. 또한 암시적으로 원시값을 지정해주기 때문에 원시값의 타입이 정수일 경우 이전 값의 +1, 문자열인 경우 해당 case의 이름을 원시값으로 가진다.
원시값과 다르게 여러 타입이나 여러 값이 필요한 경우 enum은 연관된 값(AssociatedValue)를 가질 수 있으며 각 case 옆에 튜플 형태로 type을 명시해주면 된다. 이름은 가질 수도, 없을 수도 있다.
enum StudentInfo {
case basicInfo(Int, String) // 튜플 형태로 자료형과 값의 수를 정할 수 있음
case detailInfo(grade: Int, dormitory: String, birth: Int, height: Int) // firstGrade처럼 이름 없이 자료형만 넣거나 이름을 지정해줄 수 있음
}
var harry = StudentInfo.basicInfo(1, "Gryffindor") // 이름 없이 타입만 지정한 경우
harry = .detailInfo(grade: 1, dormitory: "Gryffindor", birth: 20240901, height: 180) // 이름이 있는 경우, 이미 type이 studentInfo이기 때문에 타입 생략 가능
//추가적으로 harry에 .detailInfo를 넣은 순간 .basicInfo는 없어짐
switch harry { //switch문을 통해 원하는 case의 정보를 뺄 수 있음
case .basicInfo(let grade, var dormitory): // 이름이 없던 case의 연관값이라도 상수나 변수로 선언하여 사용 가능
print(grade, dormitory)
case let .detailInfo(grade, dormitory, birth, height) : // 이름을 정해둔 경우 정해진 이름을 사용해야 함
// 상수나 변수로 통일할 경우 일일이 이름 앞에 선언하는 대신 가장 앞에 붙여줄 수 있음
print(birth, height) //harry에는 detailInfo가 들어있으므로 이부분이 출력 됨
}
enum dormitoryColor: String, CaseIterable { // 원시값의 타입을 먼저 정하고 그 뒤에 CaseInterable을 붙여야 함
case gryffindor = "red"
case slytherin = "green"
case ravenclaw = "blue"
case hufflepuff = "yellow" //모두 통일된 타입의 값을 하나씩만 가질 수 있음
}
for yourColor in dormitoryColor.allCases {
print("\(yourColor)'s color is", yourColor.rawValue) // .rawValue를 통해 원시값을 찾을 수 있음
}
/* gryffindor's color is red
slytherin's color is green
ravenclaw's color is blue
hufflepuff's color is yellow */