Enumeration
Apple Official Document enumeration Apple official document Chinese translation enumeration
Enumeration syntax
enum SomeEnumeration { // enumeration definition goes here}
enum CompassPoint { case north case south case east case west}var directionToHead = CompassPoint.westdirectionToHead = .east
enum Planet { case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune}
Using a switch statement to match an enumeration value
directionToHead = .southswitch 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")}// prints "Watch out for penguins"
If you cannot provide a case for all enumeration members, you can also provide a ==default== condition to include those members that cannot be explicitly written out:
let somePlanet = Planet.earthswitch somePlanet { case.earth: print("Mostly harmless") default: print("Not a safe place for humans")}// Prints "Mostly harmless"
Associated value
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).")}// Prints "QR code: ABCDEFGHIJKLMNOP."
If all the related values for an enumeration member are extracted as constants, or if all are extracted as variables, for brevity, you can use a separate var or let to label the member names before:
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."
Original value
Enumeration members can be pre-populated with default values of the same type (known as raw values).
enum ASCIIControlCharacter: Character { case tab = "\t" case lineFeed = "\n" case carriageReturn = "\r"}
Implicitly specified original value
You do not have to explicitly assign each member an original value when you are manipulating an enumeration that stores integers or string primitives. When you don't have an assignment, Swift will automatically assign you a value.
enum Planet: Int { case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune}enum CompassPoint: String { case north, south, east, west}let earthsOrder = Planet.Earth.rawValue // earthsOrder is 3 let sunsetDirection = CompassPoint.west.rawValue // sunsetDirection is "west"
Class from the original value.
When an enumeration is defined with the original value type, the enumeration automatically receives an initializer (called a formal parameter of ==rawvalue==) that can accept the value of the original value type, and then returns an enumeration member or nil
let possiblePlanet = Planet(rawValue: 7) // possiblePlanet is of type Planet? and equals Planet.Uranus
The original value initializer is a failed initializer
let positionToFind = 11if 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 enumeration
A recursive enumeration is an enumeration that has another enumeration as the associated value of an enumeration member. Use the ==indirect== keyword before declaring an enumeration member to make it clear that it is recursive.
enum ArithmeticExpression { case number(Int) indirect case addition(ArithmeticExpression, ArithmeticExpression) indirect case multiplication(ArithmeticExpression, ArithmeticExpression)}
==indirect== can be written before enumeration to allow the entire enumeration member to be recursive when needed:
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))
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"
SWIFT4 enumeration, self-study notes