Swift

Enumerations

Creating our own data types

What are Enumerations?

Enumerations, also known as “enums” are ways for us to create and define our own data types in Swift with their own named values. To create an enum, it’s super simple.

enum IceCreamFlavor {
    case chocolate, vanilla, strawberry
}

We just write ‘enum’, give it a name (name of the data type, like ‘Integer’, ‘String’, etc, but with a custom name), and a bunch of cases (the values). Now, let’s create a function based on this. (No hate on strawberry ice cream though.)

func favoriteFlavor(flavor: IceCreamFlavor) -> String? {
    if flavor == IceCreamFlavor.strawberry {
        return nil
    } else {
        return "Nice!"
    }
}
        
favoriteFlavor(flavor: IceCreamFlavor.strawberry)

We can also rewrite a bit of it to make it a bit easier to read.

enum IceCreamFlavor {
    case chocolate, 
    case vanilla, 
    case strawberry
}
        
func favoriteFlavor(flavor: IceCreamFlavor) -> String? {
    if flavor == .strawberry { //Notice how we no longer use IceCreamFlavor.strawberry but just .strawberry 
        // We do this because the IceCreamFlavor enum type is implied through the parameter where 'flavor: IceCreamFlavor' is specified.
        return nil
    } else {
        return "Nice!"
    }
}
    
favoriteFlavor(flavor: .strawberry)  // Same here as above      

We can even go one more step farther and create a switch case with this information.

func favoriteFlavor(flavor: IceCreamFlavor) -> String? {
    switch flavor {
        case .strawberry: return nil
        case .chocolate: return "Nice!"
        case .vanilla: return "Yum!"
        default: return "Eh"
    }
}

Additional Values

We can even add ‘associated values’ to our enums’ values. These values allow us to store additional information of another data type (int, string, double, etc) in the value of the enum’s data type itself. Let’s create a sprinkles case (Yes, my favorite flavor is sprinkles) that has an associated value to count how many sprinkles are there.

enum IceCreamFlavor {
    case chocolate, 
    case vanilla, 
    case strawberry,
    case sprinkles(count: Int) // Here, count is an associated value of the IceCreamFlavor enum's 'sprinkles' value.
} 

Now, we can consider this in our switch statement.

func favoriteFlavor(flavor: IceCreamFlavor) -> String? {
    switch flavor {
        case .strawberry: return nil
        case .sprinkles(let count) where count < 100: return "You need more"
        case .chocolate: return "Nice!"
        case .vanilla, .sprinkles: return "Yum!"
    default: return "Eh"
    }
}
        
favoriteFlavor(flavor: IceCreamFlavor.sprinkles(count: 50)

We have .sprinkles twice. The first time is only accepted if we have less than 100 sprinkles. The second time is accepted if we have more than 100 sprinkles. Swift goes through each switch case top to bottom and ends as soon as it finds a correct match. The same as putting a bunch of if,else if, and else statements together.

chevron_up