iOS 개발 노트
🪴열거형(Enumeration) 본문
열거형이란
하나의 주제로 연관된 데이터 멤버들로 구성되어 있는 자료형 객체이다.
- 문자열, 정수값 등 입력받아야 할 정보를 입력하는 대신, 선택하는 형식으로 동작됨.
- 열거형에서 데이터들은 열거형 객체를 정의하는 시점에 함께 정의된다. -> 데이터를 함부로 삭제하거나 변경할 수 없으며, 변경하거나 삭제하려면 객체를 정의하는 구문을 직접 수정해야 함
열거형 사용 시 좋은 경우
- 원치 않는 값이 잘못 입력되는 것을 막고 싶을 때
- 입력받을 값을 미리 특정할 수 있을 때
- 제한된 값 중에서만 선택할 수 있도록 강제하고 싶을 때
열거형으로 정의할 수 있는 데이터 집합의 예:
- 성별: 남, 여, X-gender
- 기기: iPhone, iPad, watch, mac, airPods
- 색상: 빨강, 노랑, 초록
- 국가: 한국, 일본, 중국, 미국, 호주, 캐나다
열거형의 정의
열거형 객체를 정의할 때는 enum
키워드를 사용한다. 데이터 멤버들은 case
키워드와 함께 정의함.
- 열거형의 이름은 파스칼 표기법을 따른다.
enum 열거형이름 {
case 멤버값1
case 멤버값2
case ...
}
enum Direction {
case north
case south
case east, west
}
let N = Direction.north
print(N) //north
또는 static let
키워드를 통해 타입 프로퍼티로 정의하는 것도 가능함!
enum Direction {
static let north = "북쪽"
static let west = "서쪽"
static let south = "남쪽"
static let east = "동쪽"
}
또는 연산 프로퍼티를 정의하는 것도 가능함!
enum Direction {
var north: String {
get {
return "북쪽"
}
}
var west: String {
get {
return "서쪽"
}
}
var south: String {
get {
return "남쪽"
}
}
var east: String {
get {
return "동쪽"
}
}
}
switch문 + 열거형
switch
문을 사용하면 열거형의 멤버와 비교하는 분기 구문을 사용할 수 있다.
- 열거형에 정의된 멤버를
switch
구문의case
블록 비교에 전부 사용하면default
구문은 생략 가능하다.
💡 반대로, 모든 멤버를 다 비교할 필요가 없다면 꼭 비교해야 할 일부 멤버만 비교하고 나머지는 default 구문에 맡기면 된다.
switch 비교대상 {
case 열거형.멤버1:
//실행할구문
case 열거형.멤버2:
//실행할구문
...
}
enum Direction {
case north
case south
case east, west
}
var directionToHead = Direction.north
switch directionToHead {
case .north:
print("북쪽")
case .south:
print("남쪽")
case .east:
print("동쪽")
case .west:
print("서쪽")
}
원시값(RawValue)
case에 있는 멤버 자체로는 의미 전달이 부족할 경우가 있다.
Swift에서는 열거형의 멤버에 실질적인 값을 할당할 수 있도록 허용하고 있다. 멤버에 대입된 값은 필요할 때 꺼낼 수 있다.
- rawValue으로 사용 가능한 타입: String, Character, Int, Double, Float
멤버에 대입할 값의 자료형을 열거형 이름 뒤에 타입 어노테이션으로 표기해야 한다.
enum HTTPCode: Int {
case OK = 200
case NOT_MODIFY = 304
case INCORRECT_PAGE = 404
case SERVER_ERROR = 500
}
멤버에 할당된 값을 읽을 때는 rawValue
속성을 사용해야 한다.
- 각 멤버들은 유니크한 값을 가져야 한다.(중복값 X)
enum HTTPCode: Int {
case OK = 200
case NOT_MODIFY = 304
case INCORRECT_PAGE = 404
case SERVER_ERROR = 500
}
print(HTTPCode.OK) //OK
print(HTTPCode.OK.rawValue) //200
열거형 객체의 멤버와 값은, 사용하는 시점에서 멤버에 보조 값을 설정할 수 있는 방법도 있다. 이렇게 설정된 값을 Associated Values이라고 한다.
Associcated Value는 실행 시점에서 값을 저장해야 할 필요가 있을 때 요긴하게 사용하면 될 것 같다.
enum ImageFormat {
case JPEG
case PNG(Bool)
case GIF(Int, Bool)
}
var newImage = ImageFormat.PNG(true)
print(newImage) //PNG(true)
newImage = ImageFormat.GIF(256, false)
print(newImage) //GIF(256, false)
CaseIterable
열거형에 CaseIterable 프로토콜을 채택하면,
allCases이라는 프로퍼티를 사용 가능해지는데 이를 사용하면 배열처럼 사용이 가능하다.
enum Number: Int, CaseIterable {
case one = 1
case two = 2
case three = 3
}
print(Number.allCases[0].rawValue) // 1
print(Number.allCases[1].rawValue) // 2
print(Number.allCases[2].rawValue) // 3
Unfrozen Enumeration
멤버가 추가될 가능성이 있는 열거형을 의미한다.
- switch 문에서 모든 case에 대한 처리가 명시되지 않았을 때, 컴파일러가 경고를 발생시키는 대신 처리되지 않은 case에 대해 특정 동작을 수행하도록 지정할 수 있게 해줍니다.
열거형을 switch 문으로 처리할 때, 모든 case에 대한 처리가 명시되지 않았을 경우 @unknown default
를 사용하여 처리되지 않은 case
에 대한 기본적인 동작을 정의할 수 있습니다.
enum Direction {
case north
case south
case east
case west
}
let test = Direction.east
switch test {
case .north:
print("북쪽을 선택했네요")
@unknown default:
print("알 수 없는 방향입니다.")
}
frozen Enumeration
더 이상 case가 추가되거나 변경되지 않는 즉, 불변성을 가진 열거형을 의미한다.
@frozen
이 선언되어 있다면 frozen Enumeration을 의미한다.- 컴파일러의 동작이나 내부 최적화 과정에서 사용된다.
- case가 변경되지 않는 것이 확실하기 때문에 default로 선언되는 과정을 없앨 수 있고 컴파일 속도를 향상시킬 수 있다.
- 프레임워크나 라이브러리에서 API 안정성을 위해 사용된다.
@frozen enum HTTPMethod: String, CaseIterable { case get = "GET" case post = "POST" case put = "PUT" case delete = "DELETE" }
'Swift' 카테고리의 다른 글
🪴Async/Await에 대해서 (0) | 2024.06.23 |
---|---|
🪴Swift는 Type-Safe한 언어! (0) | 2023.09.22 |
🪴변수명 표기법 (0) | 2023.06.29 |