Struct — тип-стойност (value type) в езика Swift, чиито инстанции се копират при предаване между части от код. За разлика от класовете, структурите не поддържат наследяване, но имплементират протоколи, съдържат свойства и методи и осигуряват предвидимо управление на паметта без ARC. Според Swift Programming Language Guide, 2026, struct е основният градивен блок на Swift — дори стандартните типове Int, String, Array и Dictionary са имплементирани като структури. Езикът препоръчва структурите като приоритетен избор за моделиране на данни.
Основни точки
Struct (структура) — съставен тип данни в Swift, който групира свързани свойства и методи в една цялост. За разлика от класовете, структурите са value types: при предаване на функция или присвояване на нова променлива се създава независимо копие на структурата, а не референция към оригиналния обект.
Swift използва структури за всички примитивни типове: Int, Double, String, Bool, Array, Dictionary и Set. Това означава, че дори основното число Int се държи като структура — при присвояване се създава копие. Разработчикът може да дефинира собствена структура с произволен набор от свойства и методи.
Според Swift Evolution (SE-0143), решението да се имплементират стандартните типове като структури е мотивирано от производителност и предвидимост. Value types не създават референтни цикли, не изискват броене на референции ARC и гарантират, че промяната на копието няма да засегне оригинала — това е критично за неизменяемостта на данни в многонишкови сценарии.
Value type semantics — ключовата разлика между struct и class. Когато присвоите структура на нова променлива или я предадете на функция, Swift създава независимо копие на всички данни. Всякакви промени в копието не засягат оригинала, което елиминира страничните ефекти, характерни за референтните типове.
// Пример за семантика на value type
struct Point {
var x: Double
var y: Double
}
var p1 = Point(x: 10, y: 20)
var p2 = p1 // p2 е независимо копие на p1
p2.x = 99 // Само p2 се променя
print(p1.x) // 10 — p1 непроменен
print(p2.x) // 99
Swift използва Copy-on-Write (COW) за оптимизиране на копирането. Ако няколко променливи се отнасят към една и съща структура, но никоя не променя данните, действително копиране не се извършва. Swift споделя паметта между променливите до първата мутация — тогава се създава истинско копие. Това предотвратява излишни операции по заделяне и ускорява работата с колекции.
По подразбиране методите на структурата не могат да променят нейните свойства — Swift изисква изрично посочване на mutating за методи, които правят промени. Това ограничение предпазва от случайна мутация и прави кода предвидим: ако метод не е маркиран като mutating, гарантирано няма да промените структурата.
Когато добавите ключовата дума mutating преди метода, Swift получава възможност да запише нови стойности в свойствата на структурата. Всъщност методът може дори напълно да замени инстанцията на структурата с нова чрез self = . Този механизъм се използва например в типовете Option и Result.
// Struct с mutating метод
struct Counter {
private var value: Int = 0
// Mutating метод — може да променя свойства
mutating func increment() {
value += 1
}
// Mutating метод може напълно да замени self
mutating func reset() {
self = Counter()
}
// Non-mutating метод — само за четене
func currentValue() -> Int {
return value
}
}
var counter = Counter()
counter.increment()
print(counter.currentValue()) // 1
counter.reset()
print(counter.currentValue()) // 0
Правила за mutating: структурата трябва да бъде декларирана чрез var, а не let — на константна структура не може да се извика mutating метод. Компилаторът проверява това на етапа на компилиране: опит за извикване на mutating метод върху let константа ще доведе до грешка при компилиране.
Изборът между struct и class — едно от фундаменталните решения в Swift. И двата типа могат да съдържат свойства, методи, инициализатори и да имплементират протоколи, но имат принципни разлики в семантиката на паметта, наследяването и управлението на жизнения цикъл.
| Характеристика | struct | class |
|---|---|---|
| Тип | Value type (копира се) | Reference type (референция) |
| Наследяване | Не поддържа | Поддържа |
| ARC / броене на референции | Не се изисква | Изисква ARC |
| Деинициализация | Не поддържа | Поддържа deinit |
| Промяна на свойства в константа | Само чрез var | Може чрез let (референцията е константна) |
| Преобразуване на типове | Не поддържа | Поддържа |
| Съхранение в колекции | Съхранява се директно (стойност) | Съхранява се като референция (указател) |
Структурите са предпочитани, когато данните не изискват наследяване, не трябва да имат обща идентичност (например координати, размери, конфигурация) и се предават между модули. Класовете се избират за UI компоненти (UIView, UIViewController), singleton и обекти с обща идентичност.
Apple препоръчва използването на struct като тип по подразбиране за моделиране на данни в Swift. Структурите са подходящи за повечето сценарии благодарение на предвидимата семантика на копиране и липсата на допълнителни разходи за броене на референции. Нека разгледаме типичните случаи, когато struct е оптималният избор.
Ако обектът съдържа данни без необходимост от наследяване (Product, User, Order, Point), използвайте struct. Компилаторът автоматично генерира memberwise initializer — не е нужно да пишете init ръчно. Equatable и Hashable също се имплементират автоматично за структури, чиито всички свойства отговарят на тези протоколи.
За конфигурации, настройки и флагове, които не се променят след създаване, struct е за предпочитане пред class. Константна (let) структура гарантира неизменяемост на всички вложени полета — в class това се отнася само до референцията, а не до съдържанието на обекта.
Структурите са безопасни в многонишкова среда поради value semantics. Всяка нишка получава независимо копие на данните и не влияе на други нишки. Състезателни условия между нишки са невъзможни за value types, което прави struct предпочитания избор за модели в SwiftUI (ObservableObject изисква class, но @State използва struct).
// Пример за използване на struct за модел от данни
struct User: Codable, Identifiable {
let id: UUID
var name: String
var email: String
var isPremium: Bool
// Изчисляемо свойство — non-mutating
var displayName: String {
isPremium ? "\(name) ⭐️" : name
}
}
// Автоматичен memberwise инициализатор
let user = User(
id: UUID(),
name: "Alice",
email: "alice@example.com",
isPremium: true
)
// Копирането е безопасно за многонишковост
var userCopy = user
userCopy.isPremium = false
// user.isPremium остава true
Използвайте class, когато имате нужда от наследяване (UIKit/AppKit компоненти), обща идентичност (delegate, observer) или контролиран жизнен цикъл на обекти (deinit). За всичко останало — struct.
Често задавани въпроси
Struct в Swift — тип-стойност (value type), който се копира при предаване между части от код. Структурите могат да съдържат свойства, методи, инициализатори и да имплементират протоколи. Основните типове Swift (Int, String, Array) са имплементирани като структури.
Struct — value type (копира се при присвояване), не поддържа наследяване и не изисква ARC. Class — reference type (предава се по референция), поддържа наследяване, деинициализация и броене на референции. Разработчиците препоръчват struct като тип по подразбиране.
Mutating — ключова дума, която показва, че методът на структурата може да променя нейните свойства. Без mutating компилаторът забранява модификацията на полета. Mutating методи могат да се извикват само на променливи, декларирани чрез var, а не let.
Copy-on-Write (COW) — оптимизация на Swift за структури, при която действителното копиране на данни се отлага до момента на първата мутация. Докато всички променливи само четат структурата, те споделят една област от паметта. Това повишава производителността при работа с големи колекции.
Използвайте struct за модели от данни без наследяване, конфигурации, DTO и многонишкови сценарии. Използвайте class за UI компоненти UIKit/AppKit, singleton, обекти с обща идентичност (delegate, observer) и обекти, изискващи деинициализация.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също