What are enums in Swift? How to use associated values and raw values? What advanced features do enums support?
Enums in Swift are types that define a group of related values, and are more powerful than enums in other languages. Swift enums can contain associated values, raw values, and can define methods and computed properties.
Basic Enum Definition:
swiftenum CompassPoint { case north case south case east case west } var direction = CompassPoint.north direction = .south
Associated Values:
- Each enum member can store associated values of different types
- Similar to enums with additional data
- Example:
swift
enum Barcode { case upc(Int, Int, Int, Int) case qrCode(String) } var productBarcode = Barcode.upc(8, 85909, 51226, 3) productBarcode = .qrCode("ABCDEFGHIJKLMNOP") switch productBarcode { case .upc(let numberSystem, let manufacturer, let product, let check): print("UPC: \(numberSystem), \(manufacturer), \(product), \(check)") case .qrCode(let productCode): print("QR code: \(productCode)") }
Raw Values:
- Enum members can have pre-filled values of the same type
- Access raw values using
rawValue - Must be String, Character, Int, or Float
- Example:
swift
enum Planet: Int { case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune } let earth = Planet(rawValue: 3) print(earth?.rawValue) // Optional(3)
Enum Methods:
swiftenum TrafficLight { case red, yellow, green func description() -> String { switch self { case .red: return "Stop" case .yellow: return "Caution" case .green: return "Go" } } mutating func next() { switch self { case .red: self = .green case .yellow: self = .red case .green: self = .yellow } } }
Computed Properties:
swiftenum Rectangle { case width(height: Double) case height(width: Double) var area: Double { switch self { case .width(let height): return height * 10 case .height(let width): return width * 5 } } }
Recursive Enums:
- Marked with the
indirectkeyword - Allows enum members to reference the enum itself
- Example:
swift
enum ArithmeticExpression { case number(Int) indirect case addition(ArithmeticExpression, ArithmeticExpression) indirect case multiplication(ArithmeticExpression, ArithmeticExpression) } let five = ArithmeticExpression.number(5) let four = ArithmeticExpression.number(4) let sum = ArithmeticExpression.addition(five, four) let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
CaseIterable Protocol:
swiftenum CompassPoint: CaseIterable { case north, south, east, west } let numberOfCases = CompassPoint.allCases.count for direction in CompassPoint.allCases { print(direction) }
Comparable Protocol:
swiftenum Priority: Int, Comparable { case low = 1 case medium = 2 case high = 3 static func < (lhs: Priority, rhs: Priority) -> Bool { return lhs.rawValue < rhs.rawValue } } let priority1 = Priority.high let priority2 = Priority.low print(priority1 > priority2) // true
Advanced Enum Features:
- Support for generics
- Support for protocols
- Support for extensions
- Support for initializers
- Support for subscripts
Best Practices:
- Use enums to represent finite, related sets of values
- Use associated values to pass additional data
- Use raw values to represent fixed values
- Add methods to enums to improve readability
- Use recursive enums to handle tree structures