Какие типы данных используются для стандартных коллекций (Array, Dictionary, Set) в Swift?

Ответ

Стандартные коллекции Swift (Array, Dictionary, Set) реализованы как структуры (value types), а не как классы.

Ключевые последствия:

  • Семантика копирования при записи (Copy-on-Write): При присваивании создаётся логическая копия. Физическое копирование данных происходит только при изменении одной из переменных, что оптимизирует производительность.
  • Изоляция изменений: Модификация копии не затрагивает оригинал.

Пример:

var originalArray = [1, 2, 3]
var copiedArray = originalArray // Пока что это одна ссылка на данные (Copy-on-Write)
copiedArray.append(4) // Теперь происходит физическое копирование, и массивы расходятся
print(originalArray) // [1, 2, 3]
print(copiedArray)   // [1, 2, 3, 4]

Исключение: Классы из Foundation (NSArray, NSDictionary, NSSet) являются ссылочными типами. Их использование в чистом Swift-коде обычно не рекомендуется, если не требуется совместимость с Objective-C.

Ответ 18+ 🔞

Да ты посмотри, какая хитрая жопа у этих свифтовых коллекций! Все думают: "О, Array, Dictionary — ну это ж наверняка классы, ссылочные типы, как везде". А нихуя! Это всё структуры, value types, ёпта.

Вот в чём прикол: когда ты одной переменной присваиваешь другую, типа var b = a, у тебя в голове сразу картинка, что память копируется тоннами и всё тормозит. А Swift-то не дурак, он Copy-on-Write использует, то есть "копирование при записи". Это как взять книгу в библиотеке и сказать: "Мы с тобой одну книгу читаем". Пока вы оба просто читаете — всё ок, одна книга на двоих. Но как только один из вас возьмёт и начнёт в ней хуярить ручкой, писать на полях — библиотекарь тут же выхватит у вас эту книгу и даст каждому свою отдельную копию. Вот так и тут: физическое копирование данных происходит только тогда, когда кто-то реально начинает менять массив или словарь. До этого — они просто на одни и те же данные ссылаются. Гениально, блядь!

Что это даёт на практике?

  • Изоляция, ёбта! Сделал копию, дописал туда свой элемент — оригинал остался чистеньким, как слеза младенца. Никаких неожиданных пиздецов, когда в десяти местах код дергает один и тот же массив.
  • Производительность не ебёт. Не нужно копировать гигабайты данных просто так, по приколу.

Смотри, как это выглядит в коде:

var originalArray = [1, 2, 3]
var copiedArray = originalArray // Пока что это одна ссылка на данные (Copy-on-Write)
copiedArray.append(4) // А вот тут! В этот самый момент происходит физическое копирование, и массивы расходятся
print(originalArray) // [1, 2, 3]
print(copiedArray)   // [1, 2, 3, 4]

Видишь? Пока мы только присвоили — копирования по-настоящему не было. А ткнули append — всё, скопировалось, и оригинал остался нетронутым. Красота!

НО! Есть же, сука, одно огромное "но", про которое все забывают! Это всё работает для нативных свифтовых коллекций. А есть же ещё старые, из FoundationNSArray, NSDictionary, NSSet. Вот эти ребята — чистейшей воды классы, ссылочные типы, и ведут себя соответственно: скопировал ссылку — меняешь один объект на всех. Использовать их в нормальном Swift-коде — это как на "Запорожце" в 2024 году на свадьбу приехать. Не надо так, если только тебе реально не нужно с Objective-C колбаситься.