Author: Tjeerd in ‘t Veen
Notes
We can use enum to model polymorphism. Enum is an or
type in Swift means when it has value, it will only once. For example: Traffic light could be represented as enum because it won’t show red and green at the same time.
When modelling data, if you initially using struct, see if it can lead to invalid states because struct we could easily fill the value.
For example chat application, instead of modelling the message model as struct, we could define them in enum with associated value to make the type of message clear.
import Foundation
enum Message {
case text(userId: String, date: Date)
case draft(userId: String, date: Date)
case join(userId: String, date: Date)
case leave(userId: String, date: Date)
case balloon(userId: String, date: Date)
}
Next if we want to get the value inside associated value, we could switch over the message or Using if case let to match specific enum case
We can also use enum to model subclassing.
// Where Run, Cycle, Pushups, Abs could be struct or class
enum Workout {
case run(Run)
case cycle(Cycle)
case pushups(Pushups)
case abs(Abs)
}
The downside of using enum for subclassing is we forced to match all cases when we need only one of the. But since enum will be checked on compile time, you’ll get safety net if you forgot to handle the case in your app
Enums are based on something called Algrebaic Data Types. Enums are /sum types; type that have fixed values they can represent. If enum has 7 cases, then the sum of it is the count of the cases./ where it can be only one thing at a time (or
).
“To know the number of possible values of an enum, you add (sum) the possible values of the types inside. In the case of the Day enum, the total sum is seven.”
The other side of /sum type/ is /product type./ In Swift, we have struct
as product type. When dealing with product type, the possible variations is the multiplications of each property. eg:
struct BooleanContainer {
let first: Bool
let second: Bool
}
// Hence we have 4 possible states. 2 from `first` and 2 from `second`
BooleanContainer(first: true, second: true)
BooleanContainer(first: true, second: false)
BooleanContainer(first: false, second: true)
BooleanContainer(first: false, second: false)
So when we are modeling state of an app, we should be careful with the variations that is possible to happen. The higher variations, the harder we maintain and keep track of it.
Enum with raw value means each value is defined at the compile time meanwhile enum with associated value, its associated value will be defined at the runtime.
Be careful when using enum with rawValue
, moreover when the rawValue is String. This can lead to a bug where we defined an enum with rawValue then having typo. It’s better to not rely on rawValue but switching on the enum itself. If you want to use rawvalue, we can utilize unit tests to make sure nothing breaks when renaming or refactoring enum.