애플 공식 문서를 바탕으로 정리합니다!
An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.
Enumerations in Swift are first-class types in their own right.
enum SomeEnumeration {
// enumeration definition goes here
}
enum CompassPoint {
case north
case south
case east
case west
}
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
var directionToHead = CompassPoint.west
directionToHead = .east
You can match individual enumeration values with a switch statement.
When it isn’t appropriate to provide a case for every enumeration case, you can provide a default case to cover any cases that aren’t addressed explicitly
directionToHead = .south
switch directionToHead {
case .north:
print("Lots of planets have a north")
case .south:
print("Watch out for penguins")
case .east:
print("Where the sun rises")
case .west:
print("Where the skies are blue")
default:
print("??")
}
// Prints "Watch out for penguins"
For some enumerations, it’s useful to have a collection of all of that enumeration’s cases. You enable this by writing : CaseIterable after the enumeration’s name. Swift exposes a collection of all the cases as an allCases property of the enumeration type
사용 이유: 코드의 가독성과 안전성
enum Beverage: CaseIterable {
case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases.count
print("\(numberOfChoices) beverages available")
// Prints "3 beverages available"
for beverage in Beverage.allCases {
print(beverage)
}
// coffee
// tea
// juice
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
//create new barcodes using either type:
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
//assign the same product a different type of barcode:
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
At this point, the original Barcode.upc and its integer values are replaced by the new Barcode.qrCode and its string value. Constants and variables of type Barcode can store either a .upc or a .qrCode (together with their associated values), but they can store only one of them at any given time.
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).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."
If all of the associated values for an enumeration case are extracted as constants, or if all are extracted as variables, you can place a single var or let annotation before the case name
switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
print("UPC : \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."
https://boidevelop.tistory.com/22
enumeration cases can come prepopulated with default values (called raw values), which are all of the same type.
enum TypeName: RawValueType {
case caseName = Value
}
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
When we don't assign a raw value for each case, Swift automatically assigns the values for you.
If the first case doesn’t have a value set, its value is 0.
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
In the example above, Planet.mercury has an explicit raw value of 1, Planet.venus has an implicit raw value of 2, and so on.
열거형의 새로운 인스턴스를 생성할 때 변수나 상수에 rawValue라는 매개변수로 초기화할 수 있는데 이렇게 되면 반환값으로 해당 Raw Value가 존재하면 해당 케이스의 값이 나오고 존재하지 않는 Raw Value라면 nil이 반환됩니다. 즉 옵셔널 타입으로 반환이 된다
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus
If you try to find a planet with a position of 11, the optional Planet value returned by the raw value initializer will be nil
let positionToFind = 11
if let somePlanet = Planet(rawValue: positionToFind) {
switch somePlanet {
case .earth:
print("Mostly harmless")
default:
print("Not a safe place for humans")
}
} else {
print("There isn't a planet at position \(positionToFind)")
}
// Prints "There isn't a planet at position 11"
Recursive Enumerations는 재귀 열거형으로 어떤 열거형의 케이스에 Associated value의 타입으로 자신의 열거형 타입이 들어간 경우를 말합니다. 이렇게 자신의 열거형 타입을 사용하게 되면 해당 케이스 앞에 indirect라는 키워드를 사용해야 하는데 예를 보면 다음과 같습니다.
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
You can also write indirect before the beginning of the enumeration to enable indirection for all of the enumeration’s cases that have an associated value:
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
A recursive function is a straightforward way to work with data that has a recursive structure. For example, here’s a function that evaluates an arithmetic expression
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"