Что такое value types
Value type — это тип данных, который хранит своё значение непосредственно в переменной, и при присваивании или передаче в функцию создаётся его копия. В Swift к value types относятся структуры (struct), перечисления (enum) и кортежи (tuple). Это противоположность ссылочным типам (reference types), таким как классы (class), где переменная хранит ссылку на объект в памяти.
Как это работает
Когда вы создаёте переменную value type, для хранения данных выделяется память на стеке (stack). При присваивании одной переменной другой происходит копирование значения: каждая переменная получает собственную независимую копию данных. Изменение одной копии не влияет на другую, так как они хранятся по разным адресам в памяти.
Например:
var a = 10
var b = a // b получает копию значения a
b = 20
print(a) // 10
print(b) // 20Здесь a и b — независимые переменные типа Int (который является структурой). Изменение b не затрагивает a.
Пример со структурами
Структуры — основной способ определения value types в Swift. Рассмотрим пример:
struct Point {
var x: Int
var y: Int
}
var p1 = Point(x: 1, y: 2)
var p2 = p1 // копия структуры
p2.x = 10
print(p1.x) // 1
print(p2.x) // 10При присваивании p2 = p1 создаётся полная копия структуры. Изменение p2.x не влияет на p1, так как это разные экземпляры в памяти.
Подводные камни
- Производительность: Копирование больших структур может быть затратным. Однако Swift использует оптимизацию copy-on-write (COW) для некоторых типов, например, для
Array,DictionaryиString. Это означает, что фактическое копирование происходит только при изменении данных, а до этого несколько переменных могут разделять одно хранилище. - Вложенные value types: Если структура содержит ссылочный тип (например, класс), то при копировании структуры копируется только ссылка на объект, а сам объект остаётся общим. Это может привести к неожиданному поведению, если изменять свойства объекта через одну из копий.
- Семантика: Value types следуют семантике значений: они сравниваются по содержимому, а не по идентичности. Для сравнения двух структур нужно использовать оператор
==, который должен быть реализован (или автоматически синтезирован, если все свойства соответствуютEquatable).
Когда использовать
Value types рекомендуется использовать по умолчанию в Swift, особенно для моделей данных, которые не имеют идентичности и не требуют наследования. Это делает код более предсказуемым и безопасным в многопоточной среде, так как нет общих изменяемых состояний. Ссылочные типы (классы) стоит применять, когда нужна идентичность, наследование или общее изменяемое состояние.
Коротко
- Value type хранит значение непосредственно, при присваивании создаётся копия.
- К value types относятся
struct,enum,tuple, а также базовые типы вродеInt,String,Array. - Изменение копии не влияет на оригинал.
- Swift использует copy-on-write для оптимизации копирования больших структур.
