Какие типы значений (Value Types) существуют в Swift?

Ответ

В Swift типы значений (Value Types) — это типы, экземпляры которых копируются при присваивании новой переменной или константе или при передаче в качестве аргумента функции. Копирование обеспечивает независимость экземпляров.

Основные типы значений:

  1. Структуры (struct) — самый распространенный тип для моделирования данных.
  2. Перечисления (enum) — для представления группы связанных значений.
  3. Кортежи (tuple) — для временной группировки нескольких значений.
  4. Все базовые (примитивные) типы: Int, Double, Bool, String, Array, Dictionary, Set.
    • Важно: Array, Dictionary, Set реализованы как структуры, поэтому они также являются типами значений с семантикой copy-on-write для оптимизации производительности.

Ключевая характеристика — семантика копирования:

struct Coordinates {
    var x: Int
    var y: Int
}

var pointA = Coordinates(x: 5, y: 10)
var pointB = pointA // Происходит КОПИРОВАНИЕ значений

pointB.x = 20 // Изменяется только копия

print(pointA.x) // 5 (оригинал не изменился)
print(pointB.x) // 20

Почему это важно (преимущества):

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

Особенности работы:

  • Для изменения свойств внутри метода структуры необходимо помечать метод как mutating.
  • Типы значений по умолчанию не поддерживают наследование.
  • Они автоматически получают поэлементный инициализатор (memberwise initializer).
Сравнение с ссылочными типами (class): Критерий Тип значения (struct) Ссылочный тип (class)
Копирование Создается новая копия данных. Копируется только ссылка (указатель) на одни и те же данные.
Хранение Чаще в стеке (быстро). В куче (heap).
Наследование Нет. Есть.
Идентичность Сравнивается по значению (==). Сравнивается по ссылке (===).

Рекомендация Apple: Используйте типы значений по умолчанию для моделирования данных. Переходите на класс только когда необходима специфическая семантика ссылок (например, общее состояние, идентичность объекта).

Ответ 18+ 🔞

А, слушай, вот эта вся хуйня про типы значений в Swift — это, блядь, основа основ, а многие её нихуя не понимают! Сидят, как мартышлюшки, и удивляются, почему у них данные пляшут.

Представь себе, ты купил в магазине яблоко. Настоящее, блядь, яблоко. Ты его своему корежу дал подержать. У тебя своё яблоко осталось, у него — своё, отдельное. Вот это и есть тип значения (Value Type), ёпта! Передал — скопировалось, и похуй.

Из чего это говно, простите, состоит:

  1. Структуры (struct) — это, блядь, наш главный кирлер. 90% твоих моделей данных должны быть ими. Не мудри.
  2. Перечисления (enum) — когда нужно выбрать что-то одно из списка. Типа, состояние загрузки: грузим, загрузилось, или всё накрылось медным тазом с ошибкой.
  3. Кортежи (tuple) — временная парочка, типа «на, подержи эти два числа, щас быстренько посчитаю». Не для долгой жизни.
  4. Вся база: Int, String, Bool, и — внимание, ёбушки-воробушки! — даже Array и Dictionary. Да-да, они тоже структуры! Просто умные, с оптимизацией «копируй-только-когда-пиздец-нужно» (copy-on-write).

Суть в одной строчке кода, смотри сюда:

struct Координаты {
    var x: Int
    var y: Int
}

var точкаА = Координаты(x: 5, y: 10)
var точкаБ = точкаА // В этот момент, блядь, происходит МАГИЯ! Всё скопировалось!

точкаБ.x = 20 // Долбим только копию

print(точкаА.x) // 5 (оригинал в ахуе, он не тронут!)
print(точкаБ.x) // 20

Видишь? точкаБ — это уже отдельная личность, её изменения — её личные проблемы. Никаких сюрпризов.

А нахуя это всё? Преимущества:

  • Не обосрёшься в потоках. Раз у каждого своя копия, хоть десять потоков пускай её жуют — они друг другу не помешают. Потокобезопасность из коробки, ёперный театр!
  • Предсказуемость, как у швейцарских часов. Передал данные в функцию — и спи спокойно, исходная переменная не изменится, пока ты её явно не тронешь. Никаких «ой, а кто это тут нахулиганил?».
  • Быстро, блядь! Мелкие структуры живут в стеке, а доступ туда — это как в соседнюю комнату сходить, а не на другой конец города в кучу (heap).

Важные нюансы, чтоб не облажаться:

  • Хочешь поменять свойство структуры внутри её метода? Помечай метод словечком mutating. Это как сказать: «Так, народ, я ща тут внутри пошалю».
  • Наследование? Забудь. Оно тут не водится. Композиция — наш бог.
  • Инициализатор тебе заботливо сгенерируют автоматически. Бери и пользуйся.

И главное — чем это не является:

Не путай с классами (class), это вообще другая религия! Вот тебе табличка, чтобы не пиздеть:

Критерий Тип значения (struct) Ссылочный тип (class)
Копирование Создаётся НОВАЯ КОПИЯ данных. Полная. Копируется только ССЫЛКА (указатель) на одни и те же данные в памяти.
Хранение Чаще в стеке (быстро). В куче (медленнее).
Наследование Нет. Да, можно.
Идентичность Сравниваешь по значению (==). Одинаковые цифры? Значит, равны. Сравниваешь по ссылке (===). Это один и тот же объект в памяти?

Финальный вердикт от самих яблочников (Apple): Начинай всегда со структуры. Хуй заблудишься. Переходи на класс только когда реально нужна эта вся муть с общим изменяемым состоянием или идентичностью объектов. Всё остальное — на структурах, и жизнь наладится.