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 создаёт независимую копию всех данных. Любые изменения в копии не затрагивают оригинал, что исключает побочные эффекты, характерные для ссылочных типов.
// Example of value type semantics
struct Point {
var x: Double
var y: Double
}
var p1 = Point(x: 10, y: 20)
var p2 = p1 // p2 is an independent copy of p1
p2.x = 99 // Only p2 changes
print(p1.x) // 10 — p1 unchanged
print(p2.x) // 99
Swift использует Copy-on-Write (COW) для оптимизации копирования. Если несколько переменных ссылаются на одну структуру, но ни одна из них не изменяет данные, фактического копирования не происходит. Swift делит память между переменными до первой мутации — тогда создаётся настоящая копия. Это предотвращает избыточные allocate-операции и ускоряет работу с коллекциями.
По умолчанию методы структуры не могут изменять её свойства — Swift требует явного указания mutating для методов, которые вносят изменения. Это ограничение защищает от случайной мутации и делает код предсказуемым: если метод не помечен mutating, вы гарантированно не измените структуру.
Когда вы добавляете ключевое слово mutating перед методом, Swift получает возможность записать новые значения в свойства структуры. Фактически, метод может даже полностью заменить экземпляр структуры на новый через self = . Этот механизм используется, например, в типах Option и Result.
// Struct with mutating method
struct Counter {
private var value: Int = 0
// Mutating method — can modify properties
mutating func increment() {
value += 1
}
// Mutating method can replace self entirely
mutating func reset() {
self = Counter()
}
// Non-mutating method — read only
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 (ссылка константна) |
| Type casting | Не поддерживает | Поддерживает |
| Хранение в коллекциях | Хранится напрямую (значение) | Хранится как ссылка (указатель) |
Структуры предпочтительны, когда данные не требуют наследования, не должны иметь общей идентичности (например, координаты, размеры, конфигурация) и передаются между модулями. Классы выбирают для 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).
// Example of struct usage for data model
struct User: Codable, Identifiable {
let id: UUID
var name: String
var email: String
var isPremium: Bool
// Computed property — non-mutating
var displayName: String {
isPremium ? "\(name) ⭐️" : name
}
}
// Automatic memberwise initializer
let user = User(
id: UUID(),
name: "Alice",
email: "alice@example.com",
isPremium: true
)
// Copying is safe for multi-threading
var userCopy = user
userCopy.isPremium = false
// user.isPremium remains 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 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также