Enumeration is a very useful concept that is used to group related values together and define a new type for them. You must be familiar with enumeration in Objective-C or in C. Swift added new flavors to enum, and made it more flexible and easy to use.
To create enum in Swift, use the enum
keyword, and then you can list all the possible cases after the case
keyword:
enum LevelDifficulty{ case Easy case Medium case Hard case Advanced }
In the preceding code, we defined the new type as LevelDifficulty
to group the related values of difficulties together (Easy
, Medium
, Hard
, and Advanced
). To use this enum, you can easily create variables with the LevelDifficulty
type:
var easyMode = LevelDifficulty.Easy //Type is inferred as LevelDifficulty var mode : LevelDifficulty mode = .Hard
As we see in this example, there are various ways to create enum. In the second one, for the variable mode
, we set the type first, and then gave it a value. To set the value of a variable, we use a .
(dot) operator.
Swift makes life easy with enum. We can see this in the following example:
var power :Int switch mode { case .Easy: power = 20 case .Medium: power = 30 case .Hard: power = 50 case .Advanced: power = 90 }
Very easy, isn't it? But take care of some the very important notes in the switch
statement while using it in Swift:
It has to be exhaustive, which means that you have to cover all the possible values of enum, and list them as cases, or use the default case.
Swift doesn't support fallthrough. Unlike other languages, Swift doesn't fall through the bottom of each
switch
case into the next one. Theswitch
statement finishes its execution as soon as aswitch
case is matched without explicitly writing abreak
statement. For sure, this makes your code safer by avoiding the execution of more than oneswitch
case, by forgetting to add a break statement!
Swift gives enumerations another flavor and a great feature. This enables you to store the additional information for each member value. These associated values can be any given type, and can also be different for each member value. If you feel confused, look at the next example:
enum MissionState{ case Accomplished(Int) case Attempted(String, Int) case UnAttempted }
In this enum, in the case of Accomplished
, we provide an integer value for it, which will represent the number of stars earned in this mission. In the case of Attempted
, we provide two values for it. One is the string that represents the most progress achieved, and the other is the integer value for the number of attempts. The last one is UnAttempted
, where we don't have to provide any additional information.
So now, let's see how to use this type of enumerations:
var state = MissionState.Accomplished(3) var attemptState = MissionState.Attempted("80%", 3)
It is very easy to use this type of enumeration in the switch
statement:
switch attemptState { case .Accomplished(let stars): println("Mission accomplished with \(stars) stars") case .Attempted(let progress, let count): println("Mission attempted \(count) times with most progress \(progress)") case .UnAttempted: println("UnAttempted") }
To use the associated values in enumerations, Swift gives you the ability to label or describe these different values. This will make your code more readable and easy to use. To recreate our previous enum with labels, use the following code:
enum MissionState{ case Accomplished(stars:Int) case Attempted(missionProgress:String, attemptsCount:Int) case UnAttempted } var state = MissionState.Accomplished(stars:3) var attemptState = MissionState.Attempted(missionProgress: "80%", attemptsCount: 3)
You can see how the labels make the code very understandable and easier to read.