Enumeration?
열거형은 관련된 값으로 이루어진 그룹을 공통의 형으로 선언해 형 안전성을 보장하는 방법으로 코드를 다룰 수 있게 해줍니다.

enumeration 구현 가능 타입
[Swift는 case값이 string, character, integer, flowing 값들을 사용할 수 있습니다.]
열거형은 1급 클래스형이어서 계산된 프로퍼티를 제공하거나 초기화를 지정하거나, 초기선언을 확장해 사용할 수 있음
[enum으로 switch문을 이용시 유의사항]
다만 case의 값을 모두 포함해서 사용해야하며 그렇지않을 경우 컴파일 오류가 납니다. 하지만
만약에 열거형의 모든 cases의 처리를 기술하는게 적당하지않다면 기분(default) case를
제공함으로써 처리되지않는 case를 피할 수 있습니다.
[enumeraions 사용 방법들]
1. case내부에 타입을 추가할 수 있다.
4자리수로 연결된 바코든나 2953개의 문자로 구성된 QR코드 형태로 이루어진 두 가지 종류가 있다면 이 바코드를 아래와 같이 열거형으로 정의할 수 있다.
enum Barcode{
case ups(Int,Int,Int,Int)
case qrCode(String)
}
2. switch문을 이용한 변, 상수 재선언
이것을 Switch문에서 사용한다고 하면 변수나 상수로 선언해서 재사용이 가능합니다.
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \ (check).")
case .qrCode(let productCode):
print("QR code: \(productCode).")
}
하지만 인스턴스로 선언된 것이 상수이면 위에 let을 생략하여 코드를 간소화할수 있습니다.
3. 암시적으로 할당된 Raw 값 (Implicitly Assigned Raw Values)
열거형을 다루면서 raw값으로 Integer나 String 값을 사용할 수 있는데, 각 case별로 명시적으로 raw값을 할당할 필요는 없습니다.
만약 raw값을 할당하지 않으면 Swift에서 자동으로 값을 할당해 줍니다.
자동으로 나머지는 값을 부여해준다니,, 꽤나 코드를 줄일 수 있겠군 ?!
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
위 경우는 mercury에 1을 raw 값으로 명시적으로 할당했고 venus는 암시적으로 2 그리고 이후 값은 1증가 된 값을 자동으로 raw값으로 갖게 됩니다. 만약 String을 raw값으로 사용한다면 case텍스트가 raw값으로 자동으로 raw값으로 할당됩니다.
enum CompassPoint: String {
case north, south, east, west
}
위 경우 CompassPoint.south는 암시적으로 "south"를 raw값으로 갖습니다.
raw값은 rawValue 프로퍼티를 사용해 접근할 수 있습니다.
let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3
let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"
4. Raw 값을 이용한 초기화 (Initializing from a Raw Value)
재귀 열거자(재귀 열거자 (Recursive Enumerations)
indirect를 붙여 다른 인스턴스의를 관계 값으로 갖는 열거형이며 재귀 열거자는 case앞 또는 enum앞에 indirect라는 키워드를 붙이면 됩니다.
예제)
재귀 열거자는 다른 열거 인스턴스를 관계 값으로 갖는 열거형입니다. 재귀 열거자 case는 앞에 indirect키워드를 붙여 표시합니다.
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
만약 관계 값을 갖는 모든 열거형 case에 indirect표시를 하고 싶으면 enum키워드 앞에 indirect표시를 하면 됩니다.
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
아래 예제는 ( 5 + 4 ) * 2를 재귀 열거자로 표현한 것입니다.
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
다음은 위 재귀 열거자를 처리하는 함수입니다.
func evaluate(_ expression: ArithmeticExpression) -> Int {
switch expression {
case let .number(value):
return value
case let .addition(left, right):
return evaluate(left) + evaluate(right)
case let .multiplication(left, right):
return evaluate(left) * evaluate(right)
}
}
print(evaluate(product))
// Prints "18"