1. Introduction
In Objective-C, there is no actually integer data. Enumerations in Swift are more flexible. Developers can use enumerations as independent types without assigning value types to them, or assign values to them, which can be characters, strings, integers or floating-point data.
2. Enumeration syntax
The enum keyword in Swift is used to create enums, and each enum value is created using case. The example is as follows:
//Create last name enumeration, unlike Objective-C, Swift enumeration will not assign values by defaultenum Surname { case open case king case plum case Zhao } //Create an enum type variablevar myName = Surname.open //If the type can be automatically inferred, the enumeration type can be omittedmyName = .plum var myName2:Surname = .king
enum Planet { case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune }
switch myName { case .open: print("Subject name Zhang") case .king: print("Subject King") case .plum: print("Subject Li") case .Zhao: print("Subject name Zhao") }
Enums in Swift have an interesting feature, which can set some correlation values. Through the correlation values, developers can obtain the passed extra correlation values from the common enumeration values. The example is as follows:
enum Number { case one(count:Int) case two(count:Int) case three(count:Int) case four(count:Int) } var num = (count: 5) switch num { //Get the relevant value of numcase (let count): print(count) default: print(num) } //If all related relationships of an enum value are constants, the let keyword can also be extracted outside the brackets.switch num { //Get the relevant value of numcase let (count): print(count) default: print(num) }
With the syntax of correlation values, the flexibility of enumeration is greatly increased. For example, a shape enumeration, possible enumeration values include rectangles, circles, etc. The enumeration values of rectangles can provide correlation values of width and height, and the enumeration values of circular shapes can provide correlation values of radius, which is more flexible in development.
4. The original value of the enumeration
The original value can also be understood as setting a specific type for the enumeration, as shown below:
enum Char:String { case a = "A" case b = "B" case c = "C" } //”A“ var char =
Note that if the enum is of type Int, similar to Objective-C, the original value of the enum will be incremented in sequence after starting from the first one:
enum Char:Int{ case a = 0 case b case c } //1 var char =
The enumeration object can also be created through the original value, as shown below:
enum Char:Int{ case a = 0 case b case c } //1 var char = //b var char2 = Char(rawValue:1)
When creating an enumeration object through the original value, the creation may fail. For example, the original value passed in does not exist, and the Optional value nil will be returned.
4. Recursive enumeration
Recursive enumeration is a difficult part of Swift enumeration, and it is actually not very difficult to understand. As long as developers understand the essence of enumeration, recursive enumeration is easy to understand. First of all, recursion is an algorithm that can be simply understood as calling itself, while an enum is not actually a function. It does not perform a certain operation. It just expresses a data or it can also express an expression. The example is as follows:
enum Expression { // means adding case add // means reduction case mul }
The concept of correlation values has been mentioned earlier, so for the above example, two correlation values can be added as parameters for the add and mul enumeration values.
enum Expression { // means adding case add(Int,Int) // means reduction case mul(Int,Int) }
In this way, the following writing method can actually represent a 5+5 expression:
var exp = (5, 5)
It should be emphasized that this exp only expresses a conventional expression like 5+5, and it does not really perform 5+5 operations. Now the question is, how to express compound expressions like (5+5)*5 using the enum as above? It can be implemented using recursive enumeration, that is, (5+5) is used as the enumeration value and creates the enumeration again, and the transformation is as follows:
enum Expression { //Single-value data case num(Int) // means that the keywords added indirect are recursive enumeration indirect case add(Expression,Expression) // means reduction indirect case mul(Expression,Expression) } var exp1 = (5) var exp2 = (5) var exp3 = (exp1, exp2) var exp4 = (exp1, exp3)
The above exp4 actually expresses a process like (5+5)*5. Note that the recursive enum value must be declared with the indirect keyword. The best way to deal with recursive enumeration is through recursive functions, as shown below:
func expFunc(param:Expression) -> Int { // Make enumeration judgment switch param { //If it is a separate number, return directly case .num(let p): return p //If it is addition, recursive addition is performed case .add(let one, let two): return expFunc(one)+expFunc(two) //If it is multiplication, recursive multiplication is performed case .mul(let one, let two): return expFunc(one)*expFunc(two) } } //50 expFunc(exp4)
If all cases in the enum are recursive, the entire enum can be declared as recursive:
indirect enum Expression { //Single-value data case num(Int) // means that the keywords added indirect are recursive enumeration case add(Expression,Expression) // means reduction case mul(Expression,Expression) }
5. Summary of some key and difficult points
The syntax of enum starts with enum, each line of member definition starts with the case keyword, and one line can define multiple keywords.
enum CompassPoint { case North case South case East case West } enum Planet { case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune }
In the above example, the values of North, South, East, West are not equal to 0, 1, 2, 3, but they are their own values, and the type of the value is CompassPoint
var directionToHead = //directionToHead is a CompassPoint type that can be assigned to other values of this type//When setting the value of directionToHead, its type is known, so the type of East can be omitteddirectionToHead = .East
Use switch to separate enumeration values for different operations. The case in the switch must contain all branches of the enum, otherwise there will be an error in compilation. Of course, when it is not convenient to list all enum values, you can use default
directionToHead = .South switch directionToHead { case .North: println("Lots of planets have a north") case .South: println("Watch out for penguins") case .East: println("Where the sun rises") case .West: println("Where the skies are blue") } // Print "Watch out for penguins"
The enumerated element can be associated value. The following is an example of an enumerated barcode that can store a one-dimensional barcode (composed of 3 integers) and a two-dimensional barcode (composed of strings).
enum Barcode { case UPCA(Int, Int, Int) case QRCode(String) } //Define a variable. This variable can be assigned to 3 integers and can be assigned to a string, but they are all enumeration values of type Barcodevar productBarcode = (8, 85909_51226, 3) productBarcode = .QRCode("ABCDEFGHIJKLMNOP") //When using switch, the barcode types can be distinguished in the case, and the combined values can be obtained using variables or constants.switch productBarcode { case .UPCA(let numberSystem, let identifier, let check): println("UPC-A with value of \(numberSystem), \(identifier), \(check).") case .QRCode(let productCode): println("QR code with value of \(productCode).") } // Print "QR code with value of ABCDEFGHIJKLMNOP."
Inside case, if both types are let or var, the keyword can be advanced between case and enum types, such as:
case let .UPCA(numberSystem, identifier, check):
The enum of the original value type is followed by the data type. The members of the enumeration have been assigned the initial value when they are defined and cannot be changed. Compared with the enumeration of the combined value type, the combined value is set when the enum value is assigned to a variable.
The original value enumeration is more like the C language enumeration, such as the original value enumeration of integer type, and if the value of its member is not specified, it is incremented.
The original value enumeration is also like a dictionary type and is a two-way dictionary because it can obtain the original value of the member by enumerating the member, and the original value by obtaining the enumerated member. It can also be seen that the original value of this enum cannot appear with the same value.
//The type of the original value enumeration follows the enum name, and the data types of the original value of its member are all specifiedenum ASCIIControlCharacter: Character { case Tab = "\t" case LineFeed = "\n" case CarriageReturn = "\r" } //The original value of the enumeration member of the Int type is incremented, for example, the value of Venus is 2 and the value of Earth is 3enum Planet: Int { case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune } //The original value of the enum member can be obtained through the toRaw methodlet earthsOrder = () // The value of earthsOrder is 3, and the data type is Int //The enumeration member corresponding to the original value can be obtained through the fromRaw methodlet possiblePlanet = (7) // The data type of possiblePlanet Planet? The value is //Because the original value of fromRaw may not have a corresponding enum member, the returned type is an optional variable valuelet positionToFind = 9 if let somePlanet = (positionToFind) { switch somePlanet { case .Earth: println("Mostly harmless") default: println("Not a safe place for humans") } } else { println("There isn't a planet at position \(positionToFind)") } // There is no member with the original value of 9 in the enum definition, so print "There isn't a planet at position 9"