swift

Let's resume the description of the enumerative types.

The elements inside the enum set, in addition to having their own type, can be initialized with "raw data"; we see an example with the enum type ProductionPhases:

enum ProductionPhases: Int {

    case start = 0

    case execution = 1

    case end = 2

}

 

The differences from the previous definitions are two:

  1. ProductionPhases is defined as Int.
  2. Cases have all the same type.

It should be noted that the raw data assigned to each case must be unique: in the example it is a progressive number. The enumerative type above is very similar to the type in C or C ++. Similarly, once the raw type of the enumerative type is defined and the starting value defined, it is not necessary to enter the following values since they are deducted automatically.

Continuing to deepen the raw data/raw type arguments, an enumerated type so defined:

enum Directions: String {

    case north, east, south, west

}

 

associates the raw data "north" to north and the raw data "east" to east and so on, this is made possible by attributing the raw type String to the enum type; this is called the raw type implicit assignment. Another point to highlight is the ability to group the entire list of options under one case (as done above).

To recover raw value, use the same property:

let myDirection = Directions.east.rawValue //myDirection = "east"

 

To create a new instance of the enumeration by initializing with a specific element of the enumeration you can use the rawValue method:

let productionPhase = ProductionPhases(rawValue: 1) //productionPhase = (optional)execution

 

It is clear that this initialization is not free of errors since you might specify a non-existent raw value, so return value is an optional value, if you specify a non-existent raw value is returned nil.

let ghostPosition = 8

if let aPhase = ProductionPhases(rawValue: ghostPosition) {

    switch aPhase {

    case .start:

        print("Start")

    default:

        print("Another phase")

    }

}

else {

    print("Production phase inexistent")

}

 

In the example above, we use the optional binding to determine if the specified location exists. 

Finally, we have the recursive enumeration. The enumeration is recursive when enumerated cases have the associated value as the instance of itself. In this case, you must indicate it to the compiler by preceding the case statement with word indirect. Let's see an example:

enum ArithmeticExpression {

    case number(Int)

    indirect case sum(ArithmeticExpression, ArithmeticExpression)

    indirect case multiply(ArithmeticExpression, ArithmeticExpression)

}

 

Here we see that the sum has two operands that could be two numbers, but could also be two other expressions; is the case with nested expressions and is the typical case of recursion.The above enumeration can take three types of arithmetic expression: a simple number, a sum, and a multiplication. An arithmetic expression can be of this type (5+4)*2 where we find an arithmetic expression to the left of the * sign and a number to the right. We are faced with a nested arithmetic expression.

These are the constants appropriately defined by the enumerative type to represent the expression (5+4)*2:

let five = ArithmeticExpression.number(5)

let four = ArithmeticExpression.number(4)

let sum = ArithmeticExpression.sum(five, four)

let product = ArithmeticExpression.multiply(sum, ArithmeticExpression.number(2))

 

Using the calculate function below, the numeric values previously entered in the enumerary type are extracted by computing the result of the expression.

func calculate (_ expression: ArithmeticExpression) -> Int {

    

    switch expression {

    case let .number(value):

        return value

        

    case let .sum(first, second):

        return calculate(first) + calculate(second)

        

    case let .multiply(first, second):

        return calculate(first) * calculate(second)

    }

}

print(calculate(product)) //It prints 18

 

The switch block evaluates the past expression parameter from time to time; since this is a recursive enumerative type, this function will be invoked several times since the past parameter (multiply) is composed of several elements of type ArithmeticExpression.

When the function will face with an arithmetic expression consisting of a single numeric value, it is the case of five and four constants, will only return the past value; when, as in the case of summing or multiplication, it will be in front of arithmetic expressions it will return the sum and the product respectively. Misconception: The function is called once by the print() function; is the recursive setting of the enumerative type that makes the compiler behind the scenes all the work.

A final clarification. The keyword let has been used in a different position than the use made in the introductory paragraph in practice let .multiply(first, second) is equivalent to .multiply(let first, let second).