An enumeration defines a custom data type for a set of related values. Swift enumerations are much more flexible and powerful than we got used to in other languages. Enumerations in Swift are first-class type in their own right, they support computed properties, instance methods, custom initializers, extensions and can conform to protocols.
Syntax
Swift enumerations are introduced with the enum keyword and writing their entire definition within a pair of braces. Here's an example that defines some different types of polygons:
enum Polygon { | |
case triangle | |
case quadrilateral | |
case pentagon | |
case hexagon | |
} |
Multiple cases can be arranged on a single line separated by comas:
enum Polygon { | |
case triangle, quadrilateral, pentagon, hexagon | |
} |
You can match enumerations with various pattern matching constructs to retrieve the value of the enum, or act upon a specific case. Here's an example that prints the number of sides of the polygon for an specific case:
var figure = Polygon.triangle | |
switch figure { | |
case .triangle: | |
print("3 sides") | |
case .quadrilateral: | |
print("4 sides") | |
case .pentagon: | |
print("5 sides") | |
case .hexagon: | |
print("6 sides") | |
} | |
if (figure == Polygon.triangle) { | |
print("3 sides") | |
} |
A switch declaration must be exhaustive when considering an enumeration's cases. If one of the cases of the enum is omitted in the switch declaration the code will not compile. If you don't need to provide a case for every enumeration case, you can provide a default case:
switch figure { | |
case .triangle: | |
print("3 sides") | |
default: | |
print("The polygon is not a triangle") | |
} |
When a variable is initialized with one of the possible values of an enumeration, the type is automatically inferred. In the following example, the variable figure contains the enum value triangle and so it automatically infers its type, Polygon. We can then set it to a different Polygon value using dot syntax:
var figure = Polygon.triangle | |
figure = .pentagon |
Raw Values
Enumerations can have a value assigned to each case. Swift supports Integer, Floating Point, String and Boolean types for the value of an enum. You can access to the value assigned to each enumeration case with the rawValue property.
enum Triangle: String { | |
case equilateral = "Equilateral" | |
case isosceles = "Isosceles" | |
case scalene = "Scalene" | |
} | |
enum HTTPStatusCode: Int { | |
case badRequest = 400 | |
case unauthorized = 401 | |
case paymentRequired = 402 | |
case forbidden = 403 | |
case notFound = 404 | |
} | |
let badRequest = HTTPStatusCode.badRequest | |
print("Bad request - Status code: \(badRequest.rawValue)") |
Nested enums
Enums can be nested in order to specify sub types. To nest a type within another type you must declare its entire definition within the outer pair of braces.
Following the previous example, we can consider two new specific sub types for the triangle enum case. Triangles can be classified by various properties relating to their angles and sides. Here's an example that classifies triangles by their sides:
enum Polygon { | |
enum Triangle: String { | |
case equilateral = "Has three equal sides" | |
case isosceles = "Has two equal sides" | |
case scalene = "Has no equal sides" | |
} | |
case quadrila_teral | |
case pentagon | |
case hexagon | |
} |
Nested types can be used outside its definitions context using the dot syntax. You must prefix its name with the name of the type it is nested within:
let twoEqualSides = Polygon.Triangle.isosceles | |
print(twoEqualSides.rawValue) |
If you find this post helpful, please recommend it for others to read. In the next chapter we will cover more advanced features such as associated values, methods and properties.
Top comments (0)