The original address
Enumerations are a generic type defined for a set of related values, and the Swift enumeration is very powerful, making it more applicable to a wide range of scenarios than OC enumerations. In this article, we’ll look at the syntax and capabilities of enUms.
The enumeration of grammar
Enumeration is introduced using the enum keyword, whose entire definition is enclosed in a pair of braces:
enum CompassPoint {
case north
case south
case east
case west
}
Copy the code
Unlike C and Objective-C, Swift enumerators are not assigned a default integer value when they are created.
Enumerator traversal
Make the enumeration follow the CaseIterable protocol. Swift generates an allCases property that returns a collection of all members of the enumeration.
enum Beverage: CaseIterable {
case coffee, tea, juice
}
for beverage in Beverage.allCases {
print(beverage)
}
// coffee
// tea
// juice
Copy the code
The associated values
Associated values are a great way to attach additional information to an enumeration member. The Swift enumeration can store any type of associated value, as shown in the following example:
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
Copy the code
The code above defines an enumeration type named Barcode, where one member UPC has an associated value of type (Int, Int, Int, Int) and the other member qrCode has an associated value of type String.
Associated values can be accessed through pattern matching, as shown in the following example:
var productBarcode = .qrCode("ABCDEFGHIJKLMNOP") switch productBarcode { case let .upc(numberSystem, manufacturer, product, check): print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).") case let .qrCode(productCode): Print ("QR code: \(productCode).")} "QR code: ABCDEFGHIJKLMNOP.Copy the code
Detailed use of pattern matching will be covered in a later article.
The original value
Enumerators can be prepopulated with default values, which are called primitive values. Note: The primitive values must be of the same type.
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
Copy the code
By default, Swift supports only four types of enumerated values: integer, floating point, string, and Boolean. If you want to support more types of enumerated values, you need to implement the specified protocol, which will be covered in a later article.
Implicit assignment of the original value
Swift can automatically assign values for you when the original values used are integers or strings.
- When the original value used is an integer, the implicitly assigned value is incremented by one at a time. If the first enumerator does not set a raw value, its default raw value is 0.
enum Planet: Int {case mercury = 1, Venus, earth, Mars, Jupiter, Saturn, Uranus, Neptune} The implicit raw value for planet.Venus is 2, and so on.Copy the code
- When a string is used as the original value of an enumerator, the implicit original value of each enumerator is the name of that member.
// CompassPoint. South has the implicit original value south, and so on.Copy the code
The rawValue of an enumeration member can be accessed using the rawValue attribute:
Let earthsOrder = Planet. Earth. RawValue / / earthsOrder value of 3 let sunsetDirection = CompassPoint. West. RawValue / / SunsetDirection value for the "west"Copy the code
Initialize the enumeration instance with the original value
If a rawValue is used when defining an enumeration, an initialization method is automatically generated that takes a rawValue parameter of the rawValue type:
Let possiblePlanet = Planet(rawValue: 7) // possiblePlanet is of type like Planet? Value is the Planet UranusCopy the code
The primitive value constructor is a failable constructor because not every primitive value has a corresponding enumerator, so its return type is optional.
Recursive enumeration
A recursive enumeration is an enumeration type that is used as an associated value by one or more of its members. Prefix an enumeration member with the indirect keyword to indicate that the member is recursive:
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
Copy the code
An enumeration type can also be preceded by an indirect to indicate that all its members are recursive:
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
Copy the code
Its use is as follows:
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) // (5 + 4) * 2}} print(evaluate(product)Copy the code
Nested enumeration
Swift allows the nesting of enumerations, and when we use it, we need to make sure that one enumeration type is subordinate to another enumeration type, otherwise it will cause semantic confusion. Here’s an example:
enum Character { enum Weapon { case Bow case Sword case Lance case Dagger } enum Helmet { case Wooden case Iron case Diamond} case Thief case Warrior case Knight} let character = character.Thief let weapon = Character.Weapon.Bow let helmet = Character.Helmet.IronCopy the code
Instead of entering such a long hierarchy each time you access nested enumerators, you can access them directly using a convenient method like this:
func strength(of character: Character,
with weapon: Character.Weapon,
and armor: Character.Helmet) {
}
strength(of: .thief, with: .bow, and: .wooden)
Copy the code
Contains the enumeration
You can also embed enumerations in structures or classes. Continuing with the previous example:
struct Character {
enum CharacterType {
case thief
case warrior
case knight
}
enum Weapon {
case bow
case sword
case lance
case dagger
}
let type: CharacterType
let weapon: Weapon
}
let warrior = Character(type: .warrior, weapon: .sword)
Copy the code
Methods and Properties
Swift enumeration types can attach methods and attributes:
methods
enum Transportation {
case car(Int)
case train(Int)
func distance() -> String {
switch self {
case .car(let miles): return "\(miles) miles by car"
case .train(let miles): return "\(miles) miles by train"
}
}
}
Copy the code
The main difference from a structure or class type is that you can use self in a method to evaluate the output.
attribute
Note: Adding storage attributes is not allowed in Swift, the following code will compile an error:
enum Device {
case iPad
case iPhone
let introduced: Int // Enums must not contain stored properties
}
Copy the code
You should use calculated properties like this:
enum Device {
case iPad,
case iPhone
var introduced: Int {
switch self {
case .iPhone: return 2007
case .iPad: return 2010
}
}
}
Copy the code
A static method
Static methods are methods that can be invoked by a type name rather than a specific instance of a type. Examples are as follows:
enum Device {
static var newestDevice: Device {
return .appleWatch
}
case iPad,
case iPhone
case appleWatch
}
Copy the code
Variable method
Declare a method as a mutable method using the mutating keyword, where an instance of self can be modified, as shown in the following example:
enum TriStateSwitch {
case off, low, bright
mutating func next() {
switch self {
case .off:
self = low
case .low:
self = .bright
case high:
self = off
}
}
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
// ovenLight is now equal to .bright
ovenLight.next()
// ovenLight is now equal to .off
Copy the code
summary
Enumerations declare types that are finite collections of possible states and can have added value. Enumerations can define any organized data hierarchically through embedding, methods, associated values, and pattern matching.
Reference:
- Appventure. Me/guides/adva…
2. Docs.swift.org/swift-book/…