티스토리 뷰
나는 C#으로 한창 게임 프로그래밍을 배울 시절에 Enum를 많이 사용했던 것 같다. Enum은 case마다 각각의 정수값을 지정할 수 있고, 기본값으로 0, 1, 2 ... 가 지정되어 있어서 순서가 있는 게임 프로그래밍에 유용하게 사용했었다. Swift도 C#과 동일하게 Enum를 가지고 있는데, 사용하는 방식이 꽤 달라서 Swift속에서의 Enum사용법을 한 번 알아보려고 한다.
🙋🏼♀️ What is Enum?
열거형은 관련된 값으로 이루어진 그룹을 공통의 형으로(type) 선언해 형 안전성(type-safety)을 보장하는 방법으로 코드를 다룰 수 있게 해줍니다. C나 Objective-C가 Integer값들로 열거형을 구성한 것에 반해 Swift에서는 case값이 string, character, integer, floting 값들을 사용할 수 있습니다. 열거형은 1급 클래스 형(first-class types)이어서 계산된 프로퍼티(computed properties)를 제공하거나 초기화를 지정하거나, 초기 선언을 확장해 사용할 수 있습니다.
The Swift Language Guide에 따르면, Enum은 해당 뜻을 가진다고 한다. 쉽게 정리하자면,
- Eumerations 에서 따온 용어로 '열거형'이라고 해석.
- 관련 있는 값을 묶어둔 타입
- 타입이기 때문에 대문자 CamelCase로 나타내줘야 함
- case는 소문자 CamelCase로 나타냄 - 정수 뿐만 아니라 Hashable protocol를 따르는 모든 타입이 raw value로 지정 가능
- Swift 4.1부터 Struct, Enum에 대해서 컴파일러가 자동으로 hashValue값과 == 연산자를 구현해준다.
- 사용자가 직접 구현 가능 - 형 안정성이 보장됨
- 상태를 나타내기에 좋은 enum
🖼 선언 방식
enum Coffee {
case vanilla, dolce, cappuccino
case latte
case mocha
case americano
case dripCoffee
}
let coffee = Coffee.latte coffee = .mocha
- 한 줄로 선언이 가능
- 처음에 타입을 명시하고 나면 .mocha형식으로만 사용해도 해당 타입을 알아서 가져옴
🖍 RawValue
Raw value은 해당 enum에 선언된 타입에 맞는 value 값들이다.
enum Coffee: Int {
case vanilla = 1, dolce, cappuccino
case latte
case mocha
case americano
case dripCoffee
}
해당 코드는 Vanilla가 1의 Raw Value를 가짐.
- Integer값의 경우에는 한 숫자만 선언하고 나머지값을 선언하지 않으면 나머지값은 선언한 숫자 뒤로 점진적으로 +1된 값을 가짐.(암묵적 RawValue 선언)
- String의 경우에는 선언되지 않으면 해당 case값을 가짐(latte = latte를 가짐)
- RawValue를 통해서 값을 초기화할 경우,
let coffee = Coffee(rawValue: 10)
- 만약 해당값에 맞는 값이 enum에 지정되어 있지 않다면 nil를 출력
- 초기화한 인스턴스 = optional이기 때문에!
optional이기 때문에, 해당 값을 사용할 때는 optional를 뗄 수 있는 장치를 해줘야 한다.
let coffee: Coffee? = Coffee(rawValue: 10)
if let coffee: Coffee = Coffee(rawValue: 10){
print(rawValue)
} else {
print("unknown")
}
📒 Method 추가
Enum 선언할 때, method도 함께 선언이 가능하다.
enum Coffee: Int {
case vanilla = 1, dolce, cappuccino
case latte
case mocha
case americano
case dripCoffee
func cup() -> String {
if self.rawValue > 3 {
return "i don't want it"
} else {
return "i like it"
}
}
}
let coffee = Coffee.americano
coffee.cup() // "i don't want it"
🖌 Associated Value
Enum 타입에 User가 추가적인 정보값을 할당할 수 있다.
enum School {
case student(String, String, int)
case professor(String, int)
}
let stud = School.student("Tom", "2012345", 20)
let prof = School.professor("Jack", 56)
☑️ Optional
⭐️⭐️optional은 enum타입이다.
public enum Optional<Wrapped> {
case none
case some(Wrapped)
}
따라서, 값과 없는 값을 포함하고 있고, Optional이라는 enum으로 감싸져 있는 것.
🛠 Switch문
enum형식은 switch문으로 편리하게 나타내어진다.
- enum의 모든 패턴들을 빠짐없이 다룰 수 있음
- switch문에는 enum안에 들어있는 모든 case들이 들어있어야 하고
- 만약 하나라도 없을 시에는 default를 꼭 사용해줘야 함
- 안그러면 error!!⭐️
enum Coffee {
case vanilla, dolce, cappuccino
case latte
case mocha
case americano
case dripCoffee
}
let coffee = Coffee.latte
switch coffee {
case .vanilla:
print("Vanilla")
case .dolce:
print("Dolce")
case .cappuccino:
print("Cappuccino")
case .latte:
print("Latte")
default:
print("None")
} // Prints "Latte"
enum 속에 있는 method에도 switch문을 포함할 수 있다.
enum Coffee: Int {
case vanilla = 1, dolce, cappuccino
case latte
case mocha
case americano
case dripCoffee
func cup() -> String {
switch self {
case .vanilla:
print("Vanilla")
case .dolce:
print("Dolce")
case .cappuccino:
print("Cappuccino")
case .latte:
print("Latte")
}
}
}
Associated Value에서도 switch문을 사용한다.
- Associated Value를 꺼내오는 방법은
1. if-case문을 사용
2. switch문을 사용
enum School {
case student(String, String, int)
case professor(String, int)
}
let stud = School.student("Tom", "2012345", 20)
let prof = School.professor("Jack", 56)
switch stud {
case .student(let name, let id, let age):
print("\(name), \(id), \(age)")
case .professor(let name, let age):
print("\(name)님 안녕하세요.")
} // Prints "Tom, 2012345, 20"
🤔 왜 enum엔 Switch?
- if문을 사용하는 것보다 가독성이 좋기에!
- 새로운 case가 추가되었을 때 대응하기에 좋다!
잘못된 점과 피드백은 댓글로 주시면 감사하겠습니다.
참고:
https://jusung.gitbook.io/the-swift-language-guide/language-guide/08-enumerations
https://devxoul.gitbooks.io/ios-with-swift-in-40-hours/content/Chapter-3/enums.html
'Swift' 카테고리의 다른 글
[Swift] Property (0) | 2021.02.21 |
---|---|
[Swift] Struct와 Class의 차이 (0) | 2021.02.19 |