SoFunction
Updated on 2025-03-10

Detailed explanation of the usage of enum enum type in Swift

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

You can also write all enum values ​​in the same case, separated by commas:
enum Planet {
  case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

Enumerations are often used in combination with Switch statements, as shown below:
switch myName {
case .open:
  print("Subject name Zhang")
case .king:
  print("Subject King")
case .plum:
  print("Subject Li")
case .Zhao:
  print("Subject name Zhao")
}

3. The relevant values ​​of the enumeration

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"