열거형 (Enumerations)
/* The Swift Language Guide (한국어)를 공부합니다. */
열거형은 같은 특징을 가지는 값들을 하나의 그룹으로 관리하기 위한 개념입니다.
열거형을 사용하면 type-safety를 보장할 수 있습니다.
( type-safety란, 하나의 enum 그룹의 요소 외에는 사용할 수 없도록 하는 것입니다.)
Swift에서는 C와 반대로 case값이 string, character, integer, floating 값을 사용할 수 있습니다.
열거형은 1급 클래스 형이기 때문에 computed properties(계산된 프로퍼티)를 제공하거나, 초기 선언을 확장해 사용할 수 있습니다.
열거형 문법 (Enumeration Syntax)
enum키워드를 사용합니다.
enum CompassPoint {
case north, south
case east
case west
}
-> Swift에서는 0, 1, 2, 3으 값을 갖지 않습니다.
-> 또한 콤마(,)를 이용하여 구분할 수 있습니다.
-> 열거형은 새로운 형(type)을 정의하는. 것이므로, 대문자로 시작해야 합니다.
var direction = CompassPoint.west
direction = .east
-> directiong형이 CompassPoint로 한번 정의가 되면, 다음부터는 dot을 이용해서 값을 할당할 수 있습니다.
Switch 구문에서 열거형 값 매칭 하기 (Matching Enumeration Values with a Switch Statement)
각 열거형을 switch구분을 이용하여 매칭 할 수 있습니다.
direction = .south
switch direction{
case .north:
print("north")
case .south:
print("souoth")
case .east:
print("east")
case .west:
print("west")
}
-> switch 문을 사용하고 싶다면, 모든 case에 대해서 작성을 해야 합니다.
direction = .south
switch direction{
case .north:
print("north")
case .south:
print("souoth")
default:
print("default")
}
-> 만약 모든 case에 대해서 작성하고 싶지 않다면, default를 작성해줍니다.
관련 값 (Associated Values)
열거형의 각 case에 custom type의 추가적인 정보를 저장할 수 있습니다.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
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).")
}
-> 관련 값을 이용하면 같은 형을 가지고 있지만, 다른 형태의 case를 설정할 수 있습니다.
Raw 값 (Raw Values)
case에 Raw 값을 지정할 수 있습니다.
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
-> raw값은 열거형을 처음 선언할 때 정의되어서 각 case문들은 항상 같은 값을 가집니다.
암시적으로 할당된 Raw 값 (Implicitly Assigned Raw Values)
enum Number: Int{
case one = 1, two, three, four, five, six, seven, eight, nine, ten
}
-> 위와 같이 명시적으로 one에 1을 raw값으로 할당하였고, 그 이후의 변수에 대해서 암시적으로 1이 증가된 값이 할당됩니다.
enum CompassPoint: String {
case north, south, east, west
}
-> 위와 같이 String을 raw값으로 사용한다면 자동으로 각각의 case가 raw값으로 할당됩니다. (CompassPoint.south = "south")
let twoNumber = Number.two.rawValue
// two is 2
let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"
-> raw값은 rawValue프로퍼티를 사용해 접근할 수 있습니다.
Raw 값을 이용한 초기화 (Initializing from a Raw Value)
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus
-> raw값을 이용하여서 열거형 변수를 초기화 할 수도 있습니다.
-> 만약 rawValue에 해당하는 값이 없다면 nil이 저장됩니다.
재귀 열거자 (Recursive Enumerations)
재귀 열거자는 다른 열거 인스턴스를 관계 값으로 갖는 열거형입니다. case앞에 indirect키워드를 붙여 표시합니다.
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
-> 만약 모든 case에 indirect표시를 하고 싶다면 enum 키워드 앞에 indirect를 표시하면 됩니다.
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"
-> ( 5 + 4 ) * 2 를 처리하는 함수입니다.