Extension (расширение) - это мощный механизм Swift, позволяющий добавлять новую функциональность к существующим типам, даже если у вас нет доступа к их исходному коду.
extension Double {
var km: Double { return self * 1_000.0 }
var cm: Double { return self / 100.0 }
}
extension Int {
func repetitions(task: () -> Void) {
for _ in 0..<self { task() }
}
}
extension CGRect {
init(center: CGPoint, size: CGSize) {
let origin = CGPoint(x: center.x - size.width/2, y: center.y - size.height/2)
self.init(origin: origin, size: size)
}
}
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex { decimalBase *= 10 }
return (self / decimalBase) % 10
}
}
extension 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
}
}
}
extension MyType: SomeProtocol {
// реализация требований протокола
}
extension UIView {
var tagString: String = "" // Ошибка: Extensions cannot contain stored properties
}
Решение: Использовать ассоциированные объекты или вычисляемые свойства
extension UIViewController {
deinit { print("Deinit") } // Ошибка
}
extension UIView {
var x: CGFloat {
didSet { } // Ошибка
}
}
extension String {
override func lowercased() -> String { // Ошибка
return "custom implementation"
}
}
Исключение: Можно переопределять методы в extension'ах внутри того же модуля (т.н. "@objc dynamic" методы)
Организация кода:
// Разделяем функциональность по extensions
class MyViewController: UIViewController {
// основной код
}
extension MyViewController: UITableViewDataSource { ... }
extension MyViewController: UITableViewDelegate { ... }
Protocol-Oriented Programming:
protocol Flyable { ... }
extension Flyable {
func fly() { print("Flying!") }
}
Default реализации:
protocol Identifiable {
var id: String { get }
}
extension Identifiable {
var id: String { return UUID().uuidString }
}
Можно в extension:
Нельзя в extension:
Extensions - это мощный инструмент для организации кода и расширения функциональности без модификации исходных типов.