Swift - Enumerations



An enumeration is a user-defined data type that consists of a group of related values and provides a way to work with those values in a type-safe manner. Enumeration generally does not provide value to each case but if you want to you can assign value to each enumeration case and the value can be of any type such as string, int, float, or character.

Enumeration in Swift

We can define enumeration using the enum keyword followed by the name and curly braces, where the curly braces contain the enumeration cases using the case keyword. The enumeration name should start with a capital letter (Ex: enum DaysofaWeek).

Syntax

Following is the syntax of the enumeration −

enum EnumName {
   // enumeration cases
   case value1
   case value2
   ...
   case valueN
}

We can also define multiple enumeration cases into a single line, where each case is separated by commas.

enum EnumName {
   // enumeration cases
   case value1, value2, value3,…,valueN
}

Example

Following Swift's example to demonstrate how to create an enum −

enum CarColor {
   // enum values
   case Blue
   case Green
   case White
   case Off-white
}

Creating Variable of Enumeration in Swift

In enumeration, we can directly create a variable of enumeration type and assign a case to it. We can assign a case to an enum variable using dot(.) notation, where dot notation is followed by the value(for example: .value).

Syntax

Following is the syntax for creating an enum variable −

var variableName : EnumName 

Following is the syntax for assigning a value to an enum variable −

variableName = .enumValue

Example

Swift program to create and access an enum variable.

// Defining an enumeration with cases representing subjects
enum Subjects {
   case Maths
   case Science
   case Social
   case English
   case Hindi
   case ComputerProgramming
}

// Creating and assigning value to an enum variable 
var name: Subjects = .English

// Access the value of the enum variable and display data accordingly
switch name {
   case .English, .Hindi, .ComputerProgramming:
      print("Elective subjects!")
   case .Maths, .Science, .Social:
      print("Compulsory subjects")
}

Output

It will produce the following output −

Elective subjects!

Example

Swift program to create and access an enum variable.

// Defining an enumeration with cases representing car colour
enum Subjects {
   case Black
   case Blue
   case MidnightGray
   case White
   case OffWhite
   case Silver
}

// Creating and assigning value to an enum variable 
var color: Subjects = .Blue

// Using an if statement to check the enum value
if color == .Blue {
   print("Dark edition of car")
}

Output

It will produce the following output −

Dark edition of car

Enumeration with Raw Values in Swift

In enumeration, we can also assign values to the enum cases and these values are known as raw values. Raw values can be strings, characters, or any of the integer or floating-point number types. Each raw value must be unique within its enumeration declaration and of the same type.

Syntax

Following is the syntax for assigning raw values to the enum cases −

enum enumName : Type{
   // enum values
   case value1 = RawValue1
   case value2 = RawValue2
}

Accessing Raw Values

We can access raw values with the help of a pre-defined property named rawValue. The rawValue property is used to retrieve the raw value associated with the specified enum case.

Syntax

Following is the syntax of the rawValue property −

let variableName = enumName.enumCase.rawValue

Example

Swift program to access raw values of enumeration using rawValue property.

// Defining an enumeration with cases representing car colour
enum CarColor : Int {
   case Black = 2
   case Blue = 4
   case OffWhite = 5
   case Silver = 6
}

// Accessing the raw value
var colorCount = CarColor.Blue.rawValue

// Displaying the raw values
print("Raw Value:", colorCount)
Output

It will produce the following output −

Raw Value: 4

Implicitly Assigning Raw Values

When integers or strings are used as raw values for enum cases, then it is not necessary to specify values for each enum case because Swift will automatically assign values for each enum case. Such type of method is known as implicitly assigning raw values.

When we use Integer type as a raw value for enum cases and provide a raw value to the first case, then Swift will automatically assign raw values to the subsequent cases where the assigned value to the current case is greater than the previous case.

Example

Swift program to implicitly assign raw values of Integer type.

// Defining an enumeration with cases representing marks subject 
enum SubjectMarks: Int {

   // Assigning raw value to the first case
   // Now Swift will automatically assign raw values to the cases
   // for english = 41, hindi = 42, and physics = 43
   case maths = 40, english, hindi, physics
}

// Accessing the raw value
let marks = SubjectMarks.hindi.rawValue

print("Marks of hindi = ", marks)
Output

It will produce the following output −

Marks of hindi =  42

If we do not assign raw value to the first case, then by default Swift will assign zero to the first case and then 1 to the second case, 2 to the third case and so on.

Example

// Defining an enumeration with cases representing marks subject 
enum SubjectMarks: Int {
   // Here we do not assign raw value to the first case
   // So Swift will automatically assign default raw values
   case maths         // Default raw value = 0
   case english       // Default raw value = 1
   case hindi         // Default raw value = 2
   case physics       // Default raw value = 3
}

// Accessing the raw value
let marks = SubjectMarks.hindi.rawValue

print("Marks of hindi = ", marks)
Output

It will produce the following output −

Marks of hindi =  2

When we use String type as a raw value for enum cases and do not provide raw value to the cases. Then by default, Swift will implicitly assign the case’s name as a raw value.

Example

Swift program to implicitly assign raw values of String type.

// Defining an enumeration with cases representing subject names 
enum Subjects: String{
   // Here we do not assign raw value to the cases
   // So Swift will automatically assign default raw values
   case maths         // Default raw value = maths
   case english       // Default raw value = english
   case hindi         // Default raw value = hindi
   case physics       // Default raw value = physics
}

// Accessing the raw value
let marks = Subjects.hindi.rawValue

print("Marks of hindi = ", marks)
Output

It will produce the following output −

Marks of hindi =  hindi

Initializing from a Raw Value

While defining an enumeration with raw value type, Swift automatically creates an initializer for that enumeration which takes raw values as a parameter and returns an optional value(either a case or nil). If the raw value matches any of the given cases, then the initializer will return that case wrapped in the optional whereas if the raw value does not match any of the given cases then it will return nil.

Example

Swift program to initialize from raw value.

// Defining an enumeration with raw values of string type
enum Fruits: String {
   case value1 = "Mango"
   case value2 = "Apple"
   case value3 = "Banana"
   case value4 = "Orange"
}

// Initializing from raw values
if let result = Fruits(rawValue: "Apple") {
   print("Case '\(result)' is found for the given raw value")
} else {
   print("No is case found")
}
Output

It will produce the following output −

Case 'value2' is found for the given raw value

Enumeration with Associated Values in Swift

Enumeration with associated values is the most important feature provided by Swift. It allows us to add some additional information with each case of enumeration. It is commonly used in scenarios where a type can have different variations with different associated data.

Example

Swift program to demonstrate enumeration with associated values.

// Defining an enumeration with associate values
enum Student{
   case Name(String)
   case Mark(Int, Int, Int)
}

// Creating instances of the enum
var studDetails = Student.Name("Swift")
var studMarks = Student.Mark(98, 97, 95)

// Accessing the associate values
switch studMarks {
   case .Name(let studName):
      print("Student name is: \(studName).")
   case .Mark(let Mark1, let Mark2, let Mark3):
      print("Student Marks are: \(Mark1), \(Mark2), \(Mark3).")
}

Output

It will produce the following output −

Student Marks are: 98, 97, 95.

Difference between Associated Values and Raw Values

Associated Values Raw Values
Different Datatypes Same Datatypes
Ex: enum {10,0.8,"Hello"} Ex: enum {10,35,50}
Values are created based on constant or variable Prepopulated Values
Varies when declared each time Value for member is same

Enumeration with Switch Statement in Swift

As we know the Switch statement also follows the multi-way selection which means only one variable is accessed at a particular time based on the specified condition. So we can use the Switch statement to handle different cases of an enumeration.

Example

Swift program to demonstrate enumeration with Switch statement.

// Defining an enumeration with cases
enum Climate {
   case India
   case America
   case Africa
   case Australia
}

// Accessing enumeration cases using a switch statement
var season = Climate.America
season = .America
switch season {
   case .India:
      print("Climate is Hot")
   case .America:
      print("Climate is Cold")
   case .Africa:
      print("Climate is Moderate")
   case .Australia:
      print("Climate is Rainy")
}

Output

It will produce the following output −

Climate is Cold

Iterating Over Enumeration in Swift

To iterate over an enumeration we have to use the “CaseIterable” protocol. This protocol provides a collection of all cases of the given enumeration. Then we will use allCases property in the loop to iterate over each case, where the order of the iteration depends upon the order in which the cases are defined. If you want cases in any specific order, then define them accordingly.

Example

Swift program to iterate over the given enumeration.

// Defining enumeration with cases
enum Veggies: CaseIterable {
   case Onion
   case Carrot
   case Beetroot
   case Tomato
   case GreenChilly
}

// Iterating over the given enumeration
for x in Veggies.allCases {
   print(x)
}

Output

It will produce the following output −

Onion
Carrot
Beetroot
Tomato
GreenChilly

Recursive Enumeration in Swift

In Swift, we are allowed to create recursive enumeration. Recursive enumeration is a special type of enumeration in which cases can have the associated value of the enum type itself. We have to use the indirect keyword before the recursive enumeration case, it tells the compiler to add all the necessary layers of indirections. Also, not all the cases present in the given enumeration need to be marked as indirect, only those cases that involve recursion should be marked as indirect.

Example

Swift program to demonstrate recursive enumeration.

// Recursive enumeration for representing arithmetic expressions
enum Calculator {
   case number(Int)
    
   // Cases that involve recursion
   indirect case sum(Calculator, Calculator)
   indirect case product(Calculator, Calculator)
}

// Expressions
let num1 = Calculator.number(10)
let num2 = Calculator.number(12)

let addition = Calculator.sum(num1, num2)
let prod = Calculator.product(num1, addition)

// Function to evaluate an expression
func result(_ exp: Calculator) -> Int {
   switch exp {
      case let .number(value):
         return value
      case let .sum(left, right):
         return result(left) + result(right)
      case let .product(left, right):
         return result(left) * result(right)
   }
}

// Displaying result
let output = result(addition)
print("Sum is  \(output)")

Output

It will produce the following output −

Sum is  22
Advertisements