What are extensions in Swift? How to use extensions? What functionality can extensions add?
Extensions in Swift are a mechanism for adding new functionality to existing class, struct, enum, or protocol types. Extensions can add new functionality but cannot override existing functionality.
Basic Usage of Extensions:
swiftextension Int { var squared: Int { return self * self } func isEven() -> Bool { return self % 2 == 0 } } let number = 5 print(number.squared) // 25 print(number.isEven()) // false
Functionality Extensions Can Add:
-
Computed Properties:
swiftextension Double { var km: Double { return self * 1000 } var m: Double { return self } var cm: Double { return self / 100 } var mm: Double { return self / 1000 } } let oneInch = 25.4.mm print("One inch is \(oneInch) meters") -
Instance Methods:
swiftextension String { func reversed() -> String { return String(self.reversed()) } func trimmed() -> String { return self.trimmingCharacters(in: .whitespacesAndNewlines) } } let text = "Hello World" print(text.reversed()) // dlroW olleH -
Type Methods:
swiftextension Int { static func random(in range: Range<Int>) -> Int { return Int.random(in: range) } } let randomNum = Int.random(in: 1..<100) -
Initializers:
swiftextension UIColor { convenience init(hex: String) { let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) var int: UInt64 = 0 Scanner(string: hex).scanHexInt64(&int) let a, r, g, b: UInt64 } } -
Subscripts:
swiftextension Array { subscript(safe index: Int) -> Element? { return indices.contains(index) ? self[index] : nil } } let array = [1, 2, 3] print(array[safe: 1]) // Optional(2) print(array[safe: 10]) // nil -
Nested Types:
swiftextension Int { enum Kind { case negative, zero, positive } var kind: Kind { switch self { case 0: return .zero case let x where x > 0: return .positive default: return .negative } } }
Protocol Extensions:
swiftprotocol TextRepresentable { var textualDescription: String { get } } extension TextRepresentable { func describe() -> String { return "Description: \(textualDescription)" } } struct Person: TextRepresentable { var textualDescription: String } let person = Person(textualDescription: "John Doe") print(person.describe())
Conditional Extensions:
swiftextension Collection where Element: Equatable { func allEqual() -> Bool { guard let first = first else { return true } return all { $0 == first } } } extension Array where Element: Numeric { func sum() -> Element { return reduce(0, +) } }
Limitations of Extensions:
- Cannot add stored properties
- Cannot add property observers
- Cannot override existing methods
- Cannot add designated initializers
- Cannot add deinitializers
Best Practices:
- Use extensions to organize related functionality
- Use protocol extensions to provide default implementations
- Use conditional extensions to add functionality for specific types
- Avoid adding too much functionality in a single extension
- Follow the single responsibility principle for extensions