Enum

From Coder Merlin
Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder

Enumerations offer many characteristics that classes don't have, such as computed properties to provide extra information about the current value of the enumeration, and instance methods to give functionality related to the values it represents.

Enumerations can be used to define initializers and provide a starting case value, as well as being extended to add more features. Enumerations may also standardize on features in order to offer standard functionality.

Curriculum[edit]

ExercisesIcon.png
 Coder Merlin™  Computer Science Curriculum Data

Unit:

Experience Name: Enum ()

Next Experience: ()

Knowledge and skills: noneSome use of "" in your query was not closed by a matching "".

Topic areas: none

Classroom time (average):

Study time (average):

Successful completion requires knowledge: none

Successful completion requires skills: none

Basic Enum Syntax in Swift[edit]

The enum keyword is used to declare enumerations, and you must place their entire definition inside a pair of braces.

The cases of an enumeration are the enum values (such as "first," "second," "third," and "fourth") that define it. The case keyword is used to introduce new case values. A single line may contain many cases, separated by commas.

Enumerations are a class-based extension to the syntax. They extend the language's flexibility by giving classes and structs more ways of defining components via names, types, and protocols. Enums can be used in place of enumeration literals to define methods or properties. An enum is always an instance of one particular type.

enum RacePlaces {
    case first
    case second
    case third
}

Now that this is established, it can be used like this:

CoderMerlin™ Code Explorer: W0000 (1) 🟢


Enum Initialization from String[edit]

In Swift, it is possible to initialize enum from string type. Enum can be initialized with a specific case or all cases of an enum. The following example shows how to do this:

CoderMerlin™ Code Explorer: W0000 (10) 🟢


Iterating Over Enums[edit]

Sometimes, it's nice to have a collection of all of the instances in an enumeration. You may do so by adding :CaseIterable after the name of the enumeration. The allCases property of the enumeration type returns a list containing all cases.

CoderMerlin™ Code Explorer: W0000 (2) 🟢


Assigning Values to Enums[edit]

We've seen how enums are utilized for switches and conditions, but can they also store a value directly? You may refer to pre-determined values using rawValue. Let's try to accomplish so by extending our prior example and adding value.

It's also important to remember that you must label your enum with a data type before attempting to set a value to it. Now, we can assign values to our enum items and extract the value directly with the .rawValue syntax.

CoderMerlin™ Code Explorer: W0000 (3) 🟢


Associated Values[edit]

Swift's associated values refer to the ability of a type to store one of several possible values. Associated values allow Swift to be more expressive than languages like C, allowing us to provide semantic names for each possible value of a type. The semantics remain transparent with the compiler checking that it is used consistently throughout the codebase.

Why are associated types useful? One example of this is in enumerations. Let's look at an example:

 enum MyEnum { case some(String) case none }

If we were using this enum there would be no way for us to tell if it was safe to call .Some("val") or .None on this instance because both cases map onto the same underlying numeric value (zero).

We could also use associated values:

 enum MyEnum { case some(String) case none associatedtype OtherT = String }

Now we've introduced an Associated Type 'OtherT' which is a String. This allows us to separate out our types and make sure that any code calling these enums knows what the context of the data is, ensuring safety. Now we've introduced an Associated Type 'OtherT' which is a String. This allows us to separate out our types and make sure that any code calling these enums knows what the context of the data is, ensuring safety.

Conclusion[edit]

When programming in Swift, enumerations are very useful because they avoid the need to create a new type every time we want to provide a different value.

There is no doubt that we should always prefer them over other options for two reasons:

1) They avoid creating ad-hoc classes and subclasses just to agree with the compiler on how our data is structured and what it can do. Note that even if we don't need any of these features, sometimes Swift forces us to create those extra classes/subclasses anyway (e.g. when we use an enum as a property's type) so it's better not to have them in the first place;

2) they allow us to encode additional information about each case such as its name or associated values etc., so we can retrieve this information for debugging purposes or just provide a better representation to the user of what this data represents.

But it's also important to remember that just because we can create an enum with associated values, doesn't mean that we should always do so. We know that if the compiler enforces something by design, it's usually a good programming practice but the reverse is not necessarily true. Having many cases in an enum might make sense for some types of data (e.g. representing different units of measurement), but not for others (e.g. representing different accounts). It truly depends on our application and what each case represents within it.