Extension у Swift — механізм, що дозволяє додати нову функціональність існуючим типам без зміни їхнього вихідного коду. Розширення підтримують методи, обчислювані властивості, ініціалізатори, subscripts, вкладені типи та реалізацію протоколів. Згідно з Apple Documentation, 2026, extensions — ключовий інструмент для організації коду та дотримання принципу Open/Closed у Swift-проєктах.
Головне
Extension у Swift — це конструкція мови, що дозволяє розширити існуючий тип (клас, структуру, enum, протокол) новими можливостями. Це аналог категорій в Objective-C, але з більшими можливостями.
Extension може додавати:
Згідно з документацією Apple, extension не може перевизначати існуючі методи (dynamic dispatch) і не може додавати збережені властивості. Ці обмеження зберігають цілісність оригінального типу.
Extension оголошується ключовим словом extension із зазначенням типу, що розширюється.
extension Double {
var km: Double { return self * 1000.0 }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1000.0 }
}
let distance = 5.0.km
print("5 km = \(distance) meters") // 5000.0
Розширювати можна не лише власні типи, але й типи стандартної бібліотеки Swift, Foundation, UIKit та інших фреймворків. Це робить extension потужним інструментом для додавання домен-специфічної функціональності.
Extension дозволяє додавати методи екземпляра та типу до будь-якого існуючого типу.
extension String {
func isValidEmail() -> Bool {
let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
return self.range(of: emailRegex, options: .regularExpression) != nil
}
static func random(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyz0123456789"
return String((0..<length).map { _ in letters.randomElement()! })
}
}
let email = "user@example.com"
print(email.isValidEmail()) // true
let code = String.random(length: 8) // "a3f8k2m1"
Mutating методи розширюють типи-значення (struct, enum) і можуть змінювати self. Для класів mutating не потрібен. Extension може додавати mutating методи навіть до типів стандартної бібліотеки.
Extension може додавати лише обчислювані властивості — збережені властивості заборонені. Це логічно: extension не керує пам'яттю оригінального типу.
extension Date {
var isPast: Bool {
return self < Date()
}
var isToday: Bool {
return Calendar.current.isDateInToday(self)
}
}
let someDate = Date().addingTimeInterval(3600)
print(someDate.isPast) // false (one hour from now is future)
Обчислювані властивості в extension підпорядковуються тим самим правилам, що й в основній реалізації: можна створювати { get } та { get set } властивості. Swift не накладає обмежень на кількість extension для одного типу. Ви можете оголосити скільки завгодно extension для одного типу в різних файлах — це стандартна практика у великих проєктах.
Extension — кращий спосіб реалізації протоколів. Замість того щоб захаращувати основне оголошення типу, всі методи протоколу виносяться в окремий extension.
struct User {
let id: Int
let name: String
let email: String
}
// Extension per protocol — clean separation
extension User: Equatable {
static func == (lhs: User, rhs: User) -> Bool {
return lhs.id == rhs.id
}
}
extension User: Codable {
enum CodingKeys: String, CodingKey {
case id, name, email
}
}
Такий підхід розділяє відповідальність: основна структура містить лише збережені властивості, а extensions — реалізації протоколів. Swift навіть дозволяє реалізувати протокол через extension для типів, які ми не контролюємо.
Extension — не просто мовна можливість, а інструмент архітектурної організації. Правильне використання extensions робить код читабельним і підтримуваним.
// MARK: - Equatable для навігаціїprivate// MARK: - User + Displayable
extension User: Displayable {
var displayName: String {
return "\(name) (\(email))"
}
}
Згідно з Swift API Design Guidelines, extensions покращують читабельність: розробник бачить структуру даних в основному оголошенні, а логіку — в extensions. Це відповідає принципу розділення інтерфейсу.
Extension з where-обмеженнями додає методи лише для певних типів: extension Array where Element: Equatable { func isUnique() -> Bool }. Такий код лаконічний і типобезпечний — метод isUnique з'являється лише у масивів з Equatable елементами, виключаючи помилки на етапі компіляції та роблячи API чистішим, безпечнішим і зрозумілішим для інших розробників.
Поширені запитання
Ні, extension не може додавати збережені властивості. Це обмеження фундаментальне: extension не бере участі у виділенні пам'яті під екземпляр типу. Для збережених властивостей використовуйте основне оголошення типу.
Ні, extension не може перевизначати методи. Спроба оголосити метод із тією самою сигнатурою, що в існуючого, призведе до помилки компіляції. Для перевизначення використовуйте успадкування класів.
Extension додає функціональність без створення нового типу. Subclassing створює ієрархію та підтримує перевизначення. Extension не вимагає доступу до вихідного коду та працює з усіма типами.
Так, extension може бути generic, якщо тип, що розширюється, є generic: extension Array where Element: Numeric. Можна також додати generic-методи всередині extension із власними параметрами типу.
Extension не впливає на продуктивність — методи extension компілюються як звичайні методи. Для протоколів з extension використовується статична диспетчеризація, що може бути швидшою за динамічну диспетчеризацію класів.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.