![[Swift 문법] 열거형 (Enumerations) - 원시값과 연관값](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcxo5fR%2FbtrHeW2Rof9%2FP1cpLbZb4tVLbRKzGZFyA1%2Fimg.png)
열거형 구문
enum CompassPoint {
// enumeration definition goes here
case north
case south
case east
case west
}
let direction = CompassPoint.east
print(type(of: direction)) // CompassPoint
열거형 (enumeration) 은 관련된 값의 그룹(한정된 사례들, 케이스들)을 위한 타입을 정의하고, 코드에서 타입-세이프 방법으로 값을 동작하게 한다. 타입 세이프란 값에 대해 타입을 명확하도록 도와주고, 잘못된 타입의 값이 전달되는 것을 막아주는 것을 말한다.
열거형을 사용하면, 미리 정의해둔 타입의 케이스에서 벗어날 수 없으므로 코드의 가독성과 안정성이 높아진다.
enum Planet {
case mercury, venus, earth, mars, jupiter, seturn, uranus, neptune
}
여러개의 케이스는 콤마로 구분하여 한줄로 표기할 수 있다.
원시값 (Raw Values)
원시값은 열거형을 처음 정의할 때 미리 설정하는 값이다. 열거형의 케이스에 기본값을 제공하지 않아도 되지만, 필요하다면 열거형 케이스는 모두 동일한 타입의 원시값으로 미리 채워질 수 있다. (내부에서 각 케이스들에 또 다른 매칭값을 저장해 놓고, 편리하게 사용할 수 있는 것.)
원시값이 각 열거형 케이스로 제공된다면 그 값은 문자열, 문자 또는 정수 또는 부동 소수 타입일 수 있다. 각 원시값은 열거형 선언부 내에서 유일한 값이어야 한다. (cf. Hashable 프로토콜)
원시값 사용 예시
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
var tab:Character = ASCIIControlCharacter.tab.rawValue
print("T",tab,"E",tab,"S",tab,"T",tab,"!")
// T E S T !
print("T E S T !")
// T E S T !
enum HTTPCode: Int {
case OK = 200
case SEE_OTHER = 303
case NOT_FOUND = 404
case SERVER_ERROR = 500
func showStatus()->String {
switch self {
case .OK : return "OK"
case .SEE_OTHER : return "요구한 데이터를 변경하지 않음"
case .NOT_FOUND : return "페이지를 찾을 수 없음"
case .SERVER_ERROR : return "서버 긴급점검"
}
}
/* 필요할 때마다 swich 구문을 이용해서 각 케이스들을 처리해주는 것 대신,
열거형 정의할 때, 메서드를 만들어서 사용할 수 있음. */
//(=> 아니면, 연산 프로퍼티로 만들어서 사용할 수도..)
}
var networkStatus: HTTPCode = .SEE_OTHER
let resultStatus = "\(networkStatus.rawValue) : " + networkStatus.showStatus()
print(resultStatus) // 303 : 요구한 데이터를 변경하지 않음
암시적으로 할당된 원시값 (Implicit Raw Value)
원시값을 String으로 했을 때, 케이스에 원시값을 별도로 정해주지 않으면, 케이스와 문자열이 매칭된다.

원시값을 Int로 설정, 각 케이스의 원시값을 별도로 정해주지 않으면, 기본적으로 0부터 증가하며 매칭. 위 케이스에 설정된 값이 있다면 그 값부터 차례로 증가하며 매칭된다.

연관값 (Associated Values)
경우에 따라서는 각 케이스와 함께, 보다 구체적인 정보를 저장해서 사용하는 것이 유용할 수 있다. 이 추가적인 정보를 연관값 (associated value)이라 한다. 연관된 정보를 케이스에 추가적으로 저장하는 개념으로, 타입에 제한 없이 자유롭게 정의 가능하다.
enum Computer {
case cpu(core: Int, ghz:Double)
case ram(Int, String)
case hardDisk(gb: Int)
}
var cpu1 = Computer.cpu(core: 6, ghz: 1.4)
var cpu2 = Computer.cpu(core: 8, ghz: 2.4)
var ram1 = Computer.ram(16, "DDR4")
var ram2 = Computer.ram(8, "DDR3")
연관값 사용 예시
연관값이 사용된 열거형도 역시 switch 구문을 이용하여 처리할 수 있다.
이때, 열거형 케이스에 연관된 값을 상수 혹은 변수로 추출하여 사용할 수 있다. (let
또는 var
키워드 활용)
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode1 = Barcode.upc(8, 85909, 51226, 3)
var productBarcode2 = Barcode.qrCode("ABCDEFGHIJKLMNOP")
switch productBarcode1 {
case .upc(let numberSystem, let manufacurer, let product, let check)
: print("UPC : \(numberSystem), \(manufacurer), \(product), \(check).")
case .qrCode(let productCode) : print("QR code : \(productCode).")
}
// UPC : 8, 85909, 51226, 3.
케이스의 연관값을 모두 추출하려면 간결하게 케이스 이름 앞에 var
또는 let
을 선언하면 된다.
switch productBarcode2 {
case let .upc(numberSystem, manufacurer, product, check)
: print("UPC : \(numberSystem), \(manufacurer), \(product), \(check).")
case let .qrCode(productCode) : print("QR code : \(productCode).")
}
// QR code : ABCDEFGHIJKLMNOP.
💡하나의 열거형에서 원시값과 연관값을 동시에 사용하는 것은 불가능하다.
경영학 출신 개발자 Sanhan의 블로그 입니다. 개인적으로 공부한 내용이나, 모아두었던 글, 독서 내용 등을 틈틈이 정리하여 공유하려 합니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!