In this tutorial, we’ll be discussing the basics of Swift enum. You must be familiar with Enumerations if you have a previous programming background. Enumerations in Swift are really powerful and more awesome. Let’s dive right into them!
Swift Enum
As per the Apple Documentation: “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”.
In other words, Enumerations are lists of things. Enumerations in Swift are first-class types in their own right. They adopt many features traditionally supported only by classes such as defining functions within them.
Swift enum also allows us to define our own data types as well as handle various types of values. Let’s look at Swift enum syntax.
Swift Enum Syntax
An enumeration is defined using the enum
keyword followed by the name as shown below.
1 2 3 4 5 |
enum enumName { // Add values here } |
We can add different values inside the enum as shown below.
1 2 3 4 5 6 7 |
enum DaysOfAWeek{ case Monday case Tuesday case Wednesday } |
The values inside an enumeration are defined using the keyword case
. All such values are known as enumeration cases. Instead of defining every enumeration case separately, we can do it in a shorter way as shown below.
1 2 3 4 5 |
enum DaysOfAWeek{ case Monday, Tuesday, Wednesday } |
Note: As per the guidelines, Swift Enum name and values should begin with a capital letter.
An enum value is specified to a variable in the following way:
1 2 3 4 5 |
var today = DaysOfAWeek.Monday today = .Tuesday today = .Wednesday |
Once the value is defined you can reassign it without the need to specify enum name again.
Swift lets you auto-complete the value name from the list of cases defined.
Using switch statement with Swift enum
1 2 3 4 5 6 7 8 9 |
var today = DaysOfAWeek.Monday today = .Wednesday switch today { case .Monday: print("Today is Monday") case .Tuesday: print("Today is Tuesday") case .Wednesday: print("Today is Wednesday") //this gets printed. } |
Note: default case in switch is not required since we’ve covered all the enum cases in the above code.
If some of the enum cases aren’t covered we’ll need a default for sure then as shown below:
1 2 3 4 5 6 7 8 9 |
var today = DaysOfAWeek.Monday today = .Wednesday switch today { case .Monday: print("Today is Monday") case .Tuesday: print("Today is Tuesday") default: print("Today is neither Monday nor Tuesday") //this gets printed. } |
Function inside an Enum in Swift
We can define a function inside an enum in swift programming. Following is a function defined that sets the default Enum value as one of the cases:
1 2 3 4 5 6 7 8 9 10 11 12 |
enum DaysOfAWeek{ case Sunday case Monday case Tuesday case Wednesday init() { self = .Sunday } } var today = DaysOfAWeek() //Sunday |
Enums are value type and not reference type
Enums values are passed by values. The following code demonstrates an example:
1 2 3 4 5 |
var today = DaysOfAWeek() var anotherDay = today //Sunday anotherDay = .Monday //Monday |
Associated Values
Associated Values allows each case to have one or more types (e.g. Int, String, Double) that the enumeration cases can use.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
enum ValuesOfDifferentType{ case Str(String) case Inte(Int) case Numb(Double) case LatLng(Double, Double) case Boo(Bool) init(){ self = .Str("Hello World") } } var values = ValuesOfDifferentType() // returns Str("Hello World") values = .Inte(10) // returns Inte(10) values = .Boo(true) // returns Boo(true) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
func runSwitch(with value: ValuesOfDifferentType) { switch value { case .Str(let str): print("String value is (str)") case .Inte(let i) : print("Integer value is (i)") case .Numb(let d) : print("Double value is (d)") case .LatLng(let lat, let lng): print ("Lat (lat) and Lng (lng)") case .Boo(let b) : print("Boolean value is (b)") } } runSwitch(with: values) //prints String value is Hello World values = .Inte(10) runSwitch(with: values)//prints Integer value is 10 values = .Numb(12.23) runSwitch(with: values)//prints Double value is 12.23 values = .LatLng(26.213, 75.4343) runSwitch(with: values)//prints Lat 26.213 and Lng 75.4343 values = .Boo(false) runSwitch(with: values)//prints Boolean value is false |
That’s pretty awesome! Using Enums we were able to reassign a variable to different types and extract the associated values each time.
Initialising Enums With Types
The Syntax to initialise an Enum with types is given below:
1 2 3 4 5 6 7 8 9 10 |
enum DaysOfAWeek : String{ case Sunday = "Today is Sunday" case Monday = "Today is Monday" case Tuesday = "Today is Tuesday" case Wednesday } var today = DaysOfAWeek.Sunday.rawValue // returns "Today is Sunday" today = DaysOfAWeek.Wednesday.rawValue //retuns "Wednesday" |
- In the above code we’ve defined an enum with type String.
- This allows us to assign a value to cases in the enum block itself rather than doing in switch statements like we did previously.
- These values assigned to cases are known as Raw Values which have the same type as that of Enum(String in above case).
- These raw values can be returned when called upon the enum cases as
DaysOfAWeek.Sunday.rawValue
. - A case which doesn’t have any Raw Value defined would consider the case name as the raw value.
Swift Enum Raw Values doesn’t exist when the enum type is not defined.
1 2 3 4 5 6 7 |
enum DaysOfAWeek{ case Sunday = "Today is Sunday" //Compile-time Error case Wednesday } var today = DaysOfAWeek.Sunday.rawValue //error. rawValue method not found. |
Let’s simplify the switch statement now that we have values stored as raw values:
1 2 3 4 5 6 7 8 9 10 11 12 |
enum DaysOfAWeek: String{ case Sunday = "Today is Sunday" case Monday = "Today is Monday" case Tuesday = "Today is Tuesday" case Wednesday = "Today is Wednesday" } var day = DaysOfAWeek.Wednesday switch day { case .Sunday, .Monday, .Tuesday, .Wednesday: print(day.rawValue) //prints Today is Wednesday } |
Retrieve Enum case from Enum Raw Value
The Enumeration case can be retrieved from the rawValue
in the following manner.
1 2 3 4 5 6 |
var possibleDay = DaysOfAWeek(rawValue: "Today is Monday") print(possibleDay ?? "Day doesn't exist") possibleDay = DaysOfAWeek(rawValue: "Thursday") print(possibleDay ?? "Day doesn't exist") |
We pass the rawValue inside the DaysOfAWeek standard init and an optional is returned. Refer here on Optionals.
Auto-set Raw Values
Raw values can be auto-set for enum cases if it’s set for one case as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
enum Numbers :Int{ case caseOne = 100, caseTwo case caseThree } var num = Numbers.caseOne.rawValue //prints 100 num = Numbers.caseTwo.rawValue //prints 101 num = Numbers.caseThree.rawValue //prints 102 enum Numbers :Int{ case caseOne, caseTwo = 2 case caseThree } var num = Numbers.caseOne.rawValue //prints 1 num = Numbers.caseTwo.rawValue //prints 2 num = Numbers.caseThree.rawValue //prints 3 enum Numbers :Int{ case caseOne = 100, caseTwo = 2 case caseThree } var num = Numbers.caseOne.rawValue //prints 100 num = Numbers.caseTwo.rawValue //prints 2 num = Numbers.caseThree.rawValue //prints 3 |
Convert Enum case to String
1 2 3 4 5 6 7 8 9 10 11 12 |
enum DaysOfAWeek: String{ case Sunday case Monday case Tuesday case Wednesday func day()->String{ return self.rawValue } } var str = DaysOfAWeek.Sunday.day() //returns "Sunday" as a string. |
Enum HashValue vs RawValue
All enum cases have a hashValue
which is like an index of the enum cases in the order in which they are defined. The index starts from 0. HashValue exists for enums with types and enums without types. On the other hand, rawValues are used to assign a value to enum cases. RawValues exists for enums with type only.
1 2 3 4 5 6 7 8 9 10 |
enum DaysOfAWeek{ case Sunday case Monday case Tuesday case Wednesday } var day = DaysOfAWeek.Wednesday day.hashValue //returns 3 |
Optionals Are Enums
Yes indeed. Let’s see why?
Swift Optionals are a type with two cases. Either the value exists or it doesn’t. If the value exists the Optional wraps the value as Optional(value).
Let’s see how an Int Optional looks like:
1 2 3 4 |
var optionalVariable: Int? = 5 // Case when value does exist. optionalVariable = nil //Case when value doesn't exist. |
Essentially, an Optional is an Enum with two cases that we can define:
- NoValue: When the value is not defined/nil
- Value(Int): When the value is defined. We use the associated values with the enum case here.
The code for OptionalInt in the form of Enums is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
enum OptionalInt{ case NoValue case Value(Int) } var optionalInt : OptionalInt = .Value(5) switch optionalInt { case .NoValue: print("Optional doesn't contain any value") case .Value(let value): print("Optional value is (value)") //prints "Optional value is 5n" } optionalInt = .NoValue switch optionalInt { case .NoValue: print("Optional doesn't contain any value") //This is printed case .Value(let value): print("Optional value is (value)") } |
That shows that Optionals are internally Enumerations.
This brings an end to Swift Enum tutorial.
Reference: Official Documentation