Чем отличаются структуры и классы
Структуры (struct) и классы (class) в Swift — это два способа определения типов, которые отличаются прежде всего семантикой хранения и передачи данных: структуры являются типами-значениями (value types), а классы — ссылочными типами (reference types). Это означает, что при присваивании или передаче в функцию структура копируется, а класс передается по ссылке, и все ссылки указывают на один и тот же экземпляр в памяти.
Как это работает
Когда вы создаете экземпляр структуры и присваиваете его новой переменной, Swift создает полную копию значения. Изменение копии не влияет на оригинал. Классы же при присваивании не копируются: новая переменная получает ссылку на тот же объект. Изменение через любую ссылку меняет объект, и это изменение видно через все остальные ссылки.
struct PointStruct {
var x: Int
var y: Int
}
class PointClass {
var x: Int
var y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
var structA = PointStruct(x: 1, y: 2)
var structB = structA
structB.x = 10
print(structA.x) // 1 — оригинал не изменился
var classA = PointClass(x: 1, y: 2)
var classB = classA
classB.x = 10
print(classA.x) // 10 — изменилось через ссылку
## Дополнительные различия
Помимо семантики копирования, структуры и классы различаются по ряду других характеристик:
- **Наследование**: классы поддерживают наследование, структуры — нет.
- **Деинициализаторы**: классы могут иметь деинициализаторы (`deinit`), структуры — нет.
- **Приведение типов**: классы поддерживают приведение типов (`as?`, `as!`), структуры — нет.
- **Идентичность**: для классов доступна проверка идентичности через `===`, для структур — нет.
- **Изменяемость**: методы структуры, изменяющие свойства, должны быть помечены `mutating`; у классов такого ограничения нет.
- **Хранение**: структуры хранятся в стеке (если не являются свойствами класса), классы — в куче.
## Когда использовать
Выбор между структурой и классом зависит от контекста:
- **Структуры** предпочтительны для небольших неизменяемых данных, которые логически являются значениями: координаты, размеры, настройки, модели данных в SwiftUI. Они безопасны в многопоточной среде, так как копии изолированы.
- **Классы** нужны, когда требуется наследование, общее изменяемое состояние (например, синглтон) или интеграция с Objective-C. Также классы используются, когда нужно управлять жизненным циклом объекта через ссылки.
## Подводные камни
- **Неожиданное копирование**: большие структуры копируются целиком, что может снизить производительность. Однако Swift использует оптимизацию copy-on-write для некоторых типов, например `Array`.
- **Ссылочные циклы**: классы могут создавать циклы сильных ссылок, приводящие к утечкам памяти. Для их разрыва используются `weak` и `unowned`.
- **Путаница с изменяемостью**: при работе с классами легко забыть, что изменение через одну ссылку влияет на другие, что может привести к неожиданным багам.
## Коротко
- Структуры — value types: копируются при присваивании, изменения независимы.
- Классы — reference types: передаются по ссылке, изменения видны через все ссылки.
- Классы поддерживают наследование, `deinit`, приведение типов и проверку идентичности; структуры — нет.
- Для неизменяемых данных и SwiftUI предпочтительны структуры; классы — для общего состояния и наследования.Похожие вопросы
- Расскажи о своем опыте72%
- Какие задачи выполнял на прошлом месте работы66%
- "Weak" и "Unowned" в чем разница63%
- Какие есть известные проблемы с многопоточностью63%
- Какие знаешь методы жизненного цикла Activity и как они отрабатывают60%
- Для чего нужен data class60%
- Что такое reference types54%
- Какие типы коллекций существуют в Swift54%
