스위프트에서의 열거형은 다른 언어의 열거형과 많이 다르다고 한다.
열거형은 강력한 기능을 가지고 있어 잘 알아두고 사용하면 좋다고 한다.
- 유사한 종류의 여러 값을 한 곳에 모아서 정의한 것이다. 예) 요일, 월, 계절 등
- enum 자체가 하나의 데이터 타입으로, 대문자 카멜케이스를 사용하여 이름을 정의한다.
- 각 case 는 소문자 카멜케이스로 정의한다.
enum BootCamp { // 대문자 카멜케이스
case iosCamp // 소문자 카멜케이스
case androidCamp
case webCamp
}
- 각 case 는 그 자체가 고유의 값입니다. (각 case에 자동으로 정수값이 할당되지 않음)
- 각 case 는 한 줄에 개별로도, 한 줄에는 여러개도 정의할 수 있습니다.
eum 이름 {
case 이름1
case 이름2 // 개별 정의
case 이름3, 이름4, 이름5 // 다수 정의
}
그럼, 열거형을 어떻게 사용할까?
타입이 명확할 경우, 열거형의 이름을 생략할 수 있다.
switch 구문에서 사용하면 좋다.
enum Month {
case jan
case feb
case mar
}
// 열거형 타입과 케이스를 모두 사용하여도 된다.
var whr: Month = Month.jan
print(whr)
// 타입이 명확하다면 .케이스 처럼 표현해도 무방하다.
whr = .mar
print(whr)
// switch 의 비교값에 열거형 타입이 위치할 때
// 모든 열거형 케이스를 포함한다면
// default 를 작성할 필요가 없다.
switch whr {
case .jan, .feb:
print("겨울입니다.")
case .mar:
print("봄입니다.")
}
간단하게 Month라는 열거형을 만들어보았다.
변수에 열거형 타입과 케이스를 모두 사용해도 된다. 타입이 명확하다면 .케이스 라고 표현해도 된다.
그리고 열거형 타입일 경우,
switch 의 비교값(위에서 whr)이 열거형 타입이 모든 열거형 케이스를 포함한다면 default 를 작성할 필요가 없다고 한다.
// 열거형 타입과 케이스를 모두 사용하여도 된다.
var whr: Month = Month.jan
이말은 즉, whr 이란 변수를 열거형 타입으로 정해주었고
enum Month {
case jan
case feb
case mar
}
switch whr {
case .jan, .feb:
print("겨울입니다.")
case .mar:
print("봄입니다.")
}
switch 구문의 케이스에 열거형 3가지 케이스가 모두 포함되어 있기 때문에 default 가 없어도 된다.
하지만, 하나라도 포함되지 않는다면 아래와 같이 에러가 발생한다.
enum Month {
case jan
case feb
case mar
case apr
}
에러를 통해 Fix 를 누르면 다음과 같이 case 가 하나 더 생성되는 것을 확인할 수 있었다.
다음으로, rawValue(원시값)에 대해서 알아보자.
- C 언어의 enum 처럼 정수값을 가질 수 있다.
- rawValue 는 case 별로 각각 다른 값을 가져야 한다.
- 자동으로 1이 증가된 값이 할당된다.
- rawValue 를 반드시 지닐 필요가 없다면 굳이 만들지 않아도 된다.
enum Count: Int {
case one = 1
case two
case three
// one 과 원시값이 같기 때문에 ones 의 원시값을 1로 정의할 수 없다.
//case ones = 1
}
var cnt: Count = Count.one
print(cnt.rawValue)
cnt = .two
print(cnt.rawValue)
cnt = .three
print(cnt.rawValue)
========== 출력 결과 ==========
1
2
3
간단한 예를 만들어보았다.
자동으로 1씩 증가하는 것을 확인할 수 있었고
case 별로 각 다른 값을 가져야 하기 때문에 중복으로 원시값을 가질 수 없다는 것도 확인할 수 있었다.
정수 뿐만 아니라, Hashable 프로토콜을 따르는 모든 타입을 원시밗의 타입으로 지정할 수 있다.
다음 예를 통해 확인해볼 수 있었다.
enum School: String {
case elementary = "초등"
case middle = "중등"
case high = "고등"
case university // 원시값 없음
}
print("\(School.middle.rawValue)")
print("\(School.university.rawValue)")
========== 출력 결과 ==========
중등
university // 원시값을 케이스 이름으로 사용
middle 케이스의 "중등" 이라는 rawValue 라는 값을 갖지만,
university 케이스는 rawValue 의 값이 없기 때문에 case 의 이름을 원시값으로 사용한다.
그리고 원시값을 통해 초기화를 해줄 수 있다.
원시값이 열거형 케이스에 해당하지 않을 수도 있기 때문에 원시값을 통해 초기화한 인스턴스는 옵셔널 타입이다.
다음은 옵셔널 타입으로 해주지 않았을 경우 발생하는 에러다.
따라서, 다음과 같이 옵셔널 타입으로 정해줄 수 있다.
// 원시값을 통해 초기화한 열거형 값은 옵셔널 타입으므로 School 타입이 될 수 없다.
// let Heungduck: School = School(rawValue: "high")
let Heungduck: School? = School(rawValue: "high")
옵셔널에서 공부했었던 if let 구문을 통해서 사용할 수도 있다.
enum School: String {
case elementary = "초등"
case middle = "중등"
case high = "고등"
case university
}
// 원시값을 통해 초기화한 열거형 값은 옵셔널 타입으므로 School 타입이 될 수 없다.
// let Heungduck: School = School(rawValue: "high")
let Heungduck: School? = School(rawValue: "고등")
// if let 구문을 사용하면 원시값에 해당하는 케이스를 곧바로 사용할 수 있다.
if let miho: School = School(rawValue: "중등") {
print("원시값 '중등' 에 해당하는 케이스는 \(miho) 이다")
} else {
print("middle 에 해당하는 원시값이 없다.")
}
========== 출력 결과 ==========
원시값 '중등' 에 해당하는 케이스는 middle 이다
위와 같이 예를 통해 확인해볼 수 있었다.
마지막으로, 열거형에는 메서드도 추가해서 사용할 수 있다.
enum Job {
case engineer
case designer
case programmer
case developer
func printMessage() {
switch self {
case .engineer:
print("엔지니어!")
case .designer:
print("디자이너!")
case .programmer:
print("프로그래머!")
case .developer:
print("개발자!")
// 열거형의 모든 케이스가 포함되어 있기 때문에 default 사용 안함
}
}
}
Job.engineer.printMessage()
========== 출력 결과 ==========
엔지니어!
정리
열거형에 대해서 알아보았는데 직접적으로 사용해본 적은 없는 것 같다.
그래서 사용법을 익히는데 조금 시간을 더 투자한 것 같다.
열거형은 아주 광범위한 곳에서 사용될 수 있는 자료형이라고 한다.
그리고 열거형은 구조체와 함께 활용하는 것을 권장하고 있다고 한다.
열거형의 특징들을 잘 활용한다면 보다 간결한 코드를 짤 수 있지 않을까 생각한다.
- 참고 사이트 -
www.edwith.org/boostcamp_ios/lecture/11273
medium.com/@JinwooChoi/swift에서-열거형-활용하기-aaf69148e08d
'iOS > Swift' 카테고리의 다른 글
[Swift] 17. 클로저(closure) 고급 (0) | 2020.11.03 |
---|---|
[Swift] 16. 클로저(closure) 기본 (0) | 2020.11.02 |
[Swift] 14. 구조체와 클래스 비교하기 (0) | 2020.10.20 |
[Swift] 13. 클래스(class) 기본 (0) | 2020.10.20 |
[Swift] 12. 구조체(struct) 기본 (0) | 2020.10.18 |