Enumeration in Swift
Introduction to Enumerations in Swift
In Swift, an enumeration (enum) is a powerful data type that allows you to define a group of related values in a type-safe way. Enums are particularly useful when dealing with fixed categories, options, or states in an application.
Swift’s enums are more advanced than those in other languages because they can:
- Store associated values for each case.
- Have raw values of different types.
- Support computed properties and methods.
- Conform to protocols, making them more flexible.
Why Use Enumerations in Swift?
- Improves Code Readability – Organizes related values neatly.
- Prevents Invalid Values – Restricts input to predefined cases.
- Enhances Type Safety – Reduces errors with strict type checking.
- Works with Switch Statements – Provides cleaner decision-making logic.
Basic Syntax of an Enum
enum EnumName {
case case1
case case2
case case3
}
Example 1: Defining and Using an Enum
enum Direction {
case north
case south
case east
case west
}
var moveDirection: Direction = .north
print(moveDirection) // north
You can also assign an enum value using shorthand:
moveDirection = .south
Output
1. Using Enums in a Switch Statement
Enums are often used with switch statements for better control flow.
enum TrafficLight {
case red, yellow, green
}
let signal = TrafficLight.red
switch signal {
case .red:
print("Stop")
case .yellow:
print("Get
Ready")
case .green:
print("Go")
}
Output
2. Raw Values in Enumerations
Enums can have raw values, which are default values assigned to each case. These raw values can be
String
, Int
, Double
, or Character
.
enum Day: Int {
case monday = 1
case tuesday, wednesday, thursday, friday
}
print(Day.tuesday.rawValue) // 2
Output
Here, monday
is explicitly assigned 1
, and the subsequent cases automatically get
incremented values.
3. Initializing an Enum from a Raw Value
Enums with raw values can be initialized using init?(rawValue:)
.
if let today = Day(rawValue: 3) {
print("Today is \(today)")
} else {
print("Invalid day")
}
Output
4. Associated Values in Enums
Enums in Swift can store different types of values associated with each case.
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
var productCode = Barcode.upc(8, 85909, 51226, 3)
print(productCode) // upc(8, 85909, 51226, 3)
To extract associated values, use a switch statement:
switch productCode {
case .upc(let part1, let part2, let part3, let part4):
print("UPC Code:
\(part1)-\(part2)-\(part3)-\(part4)")
case .qrCode(let code):
print("QR Code:
\(code)")
}
Output
5. Enum with Methods
You can define methods inside an enum to add functionality.
enum Temperature {
case hot, cold
func description() -> String {
switch self {
case .hot:
return "It's hot outside!"
case
.cold: return "It's cold outside!"
}
}
}
let currentTemp = Temperature.hot
print(currentTemp.description()) // It's hot outside!
Output
6. Mutating Enums (Changing Enum Value in Methods)
By default, enums are immutable. To modify an enum’s value inside a method, you need to mark it as
mutating
.
enum LightSwitch {
case on, off
mutating func toggle() {
self = (self == .on) ? .off : .on
}
}
var switchState = LightSwitch.off
switchState.toggle()
print(switchState) // on
Output
7. Enum with CaseIterable Protocol (Looping Through Cases)
If you want to iterate over all cases of an enum, conform it to CaseIterable
.
enum Beverage: CaseIterable {
case coffee, tea, juice, water
}
for drink in Beverage.allCases {
print(drink)
}
Output
tea
juice
water
8. Enum with Custom Initializer
You can define a custom initializer in an enum.
enum Size {
case small, medium, large
init?(value: Int) {
switch value {
case 1:
self = .small
case 2:
self = .medium
case 3:
self = .large
default:
return nil
}
}
}
if let size = Size(value: 2) {
print("Selected size: \(size)")
} else {
print("Invalid size")
}
Output
9. Enum with Protocol Conformance
Enums can conform to protocols for added functionality.
protocol Describable {
func describe() -> String
}
enum Vehicle: Describable {
case car, bike
func describe() -> String {
switch self {
case .car:
return "A four-wheeled vehicle"
case
.bike: return "A two-wheeled vehicle"
}
}
}
let myVehicle = Vehicle.bike
print(myVehicle.describe()) // A two-wheeled vehicle
Output
Best Practices for Using Enums in Swift
- Use enums for fixed categories or states to ensure type safety.
- Use raw values when each case corresponds to a predefined value.
- Use associated values when each case needs extra information.
- Leverage switch statements for cleaner control flow.
- Conform to
CaseIterable
when needing iteration over all cases. - Use computed properties and methods to extend functionality.
- Ensure proper memory management when using enums in large applications.
Conclusion
Swift enumerations (enums) are a powerful and flexible way to work with related values efficiently. Unlike enums in other languages, Swift allows raw values, associated values, computed properties, and protocol conformance, making them highly functional.
Using enums correctly improves code organization, type safety, and readability, making Swift programming more efficient and maintainable.