The concept of a “flagged enum” is quite a powerful one as it allows you to express multiple things with just a simple number (integer). Coming from a .NET background - the ease of flagged enums found in C# is not that easily found in Swift I’ve come to realize. The expression in Swift is somewhat different and honestly a bit difficult to grasp.
Let’s give it a try:
C#
In C# you express an enum like this:
[Flags]
public enum SecurityLevel : Int{
case NoAccess = 0
case Employee = 1,
case LineManager = 2,
case DivisionManager = 4,
case RegionalManager = 8,
case CountryManager = 16}
This constructed example serves a purpose like:
var person = new Person();
person.AccessLevel = 3 //meaning access as Employee AND LineManager
This will allow us to model a Person with multiple access levels (security levels) with just a single integer. An easy way to store in the backend database as well!
Swift
So - how does this look in Swift?
public struct securityLevel : OptionsSetType {
let rawValue : Int
static let noAccess = securityLevel (rawValue: 0)
static let employee = securityLevel (rawValue: 1 << 0)
static let lineManager = securityLevel (rawValue: 1 << 1)
static let divisionManager = securityLevel (rawValue: 1 << 2)
static let regionalManager = securityLevel (rawValue: 1 << 3)
static let countryManager = securityLevel (rawValue: 1 << 4)
}
Quite a different beast, ey? How can this be the same you are thinking?
The strange << operator is called a bitwise left shift operator and and actually does what it says - it moves all bits in the array to the left by the number specified.
Looking at the securityLevel struct again, we have:
setting the value to noAccess:
0|0|0|0|0|0 = 0
setting the value employee:
0|0|0|0|0|1 = 1
setting the value lineManager:
0|0|0|0|1|0 = 2
combining the values (employee AND lineManager)
0|0|0|0|1|1 = 3
So the left shift stuff is actually initializing the struct with the value of 1, and then it moves all bits a number of slots to the left to end up with a whole new number. In our example with the combined employee and lineManager - we will see first the employee being set (rawValue:1 <<0)
- init with 1 -> 0|0|0|0|0|1
- next move it 0 places to the left -> 0|0|0|0|0|1
- end result = 1
Next is the lineManager value (rawValue: 1 << 1):
- init with 1 -> 0|0|0|0|0|1
- next move it 1 places to the left -> 0|0|0|0|1|0
- end result = 2
When combining the operations (employee AND lineManager) you are actually just performing the above operations in sequence ending up with the value 3.
Easy to understand? Not so much ;-)