swift - Enumeration
Tags: swift, programming, beginners, tutorial
Published: 2021-12-29 05:34:41

An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.

Syntax:
```swift
enum SomeEnum {
//code
}
```

Example:
```swift
enum CompassPoints{
case north
case south
case east
case west
}

enum CompassPoints{
case north,south,east,west 
}

```
**Note:**
- The values defined are its enumeration cases, we use the **case** keyword to introduce new enumeration cases.
- Swift enumeration cases don’t have an integer value set by default, unlike languages like C and Objective-C. In the CompassPoint example above, north, south, east and west don’t implicitly equal 0, 1, 2 and 3.

## Matching Enumeration Values with a Switch Statement
```swift
directionToHead = .south
switch 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"
```

## Iterating over Enumeration Cases
For some enumerations, it’s useful to have a collection of all of that enumeration’s cases. You enable this by writing : CaseIterable after the enumeration’s name. Swift exposes a collection of all the cases as an allCases property of the enumeration type.

```swift
enum Beverage: CaseIterable {
    case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases.count
print("\(numberOfChoices) beverages available")
// Prints "3 beverages available"

for beverage in Beverage.allCases {
    print(beverage)
}
// coffee
// tea
// juice

```
The syntax used in the examples above marks the enumeration as conforming to the CaseIterable protocol.

## Associated Values
We can define Swift enumerations to store associated values of any given type, and the value types can be different for each case of the enumeration if needed.

```swift
enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
```
## Raw values
As an alternative to associated values, enumeration cases can come prepopulated with default values (called raw values), which are all of the same type.

```swift
enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}
```
**Note:**
- raw values can be Strings, characters, or any of the integers or floating-point numbers type
- Each Raw values must be unique within its enumeration declare.
- Raw values are not associated values they are set of populated values.

## Implicitly assigned Raw values
When you’re working with enumerations that store integer or string raw values, you don’t have to explicitly assign a raw value for each case. When you don’t, Swift automatically assigns the values for you.

```swift
enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
```
In the example above, Planet.mercury has an explicit raw value of 1, Planet.venus has an implicit raw value of 2, and so on.

```swift
enum CompassPoint: String {
    case north, south, east, west
}
```
In the example above, CompassPoint.south has an implicit raw value of "south", and so on.

### You access the raw value of an enumeration case with its rawValue property:
```swift
let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"
```

## Initializing from a Raw Value
If you define an enumeration with a raw-value type, the enumeration automatically receives an initializer that takes a value of the raw value’s type (as a parameter called rawValue) and returns either an enumeration case or nil. You can use this initializer to try to create a new instance of the enumeration.

```swift
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus

```
## Recursive Enumerations
A recursive enumeration is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration cases. You indicate that an enumeration case is recursive by writing indirect before it, which tells the compiler to insert the necessary layer of indirection.

```swift
enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

//You can also write indirect before the beginning of the enumeration to enable indirection for all of the enumeration’s cases that have an associated value:

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}
```