В каких случаях в Swift следует использовать структуры (`struct`)?

Ответ

Структуры (struct) в Swift являются типом по умолчанию для моделирования данных. Их следует использовать, когда нужна семантика значений (value semantics).

Основные сценарии применения:

  1. Простые модели данных: Для представления сущностей, которые можно описать их свойствами (например, пользователь, точка, заказ).
    struct Point {
        var x: Double
        var y: Double
    }
    let origin = Point(x: 0, y: 0)
    var point2 = origin // Создается полная копия
    point2.x = 5 // origin.x остается 0
  2. Иммутабельность и предсказуемость: Изменение копии не влияет на оригинал, что упрощает рассуждение о коде.
  3. Потокобезопасность: Поскольку данные копируются, работа с ними в разных потоках безопаснее.
  4. Высокая производительность: Для небольших типов копирование часто эффективнее, чем подсчет ссылок (ARC), используемый классами.

Когда выбрать класс: Если требуется наследование, ссылочная семантика или управление жизненным циклом через deinit.

Ответ 18+ 🔞

Давай разберем эту вашу структуру, как говорится, по косточкам, а то народ путается, как последние идиоты.

Вот смотри, в Свифте есть эти struct, и они, блядь, по умолчанию — твои лучшие друзья для данных. Почему? Да потому что они ведут себя как нормальные, честные значения. Скопировал — и у тебя своя, отдельная, блядь, копия. Изменяешь её — оригинал спит спокойно, ему похуй. Это и есть семантика значений, или, как я это называю, "не лезь в мое, сука, я не лезу в твое".

Где их пихать, чтобы не облажаться:

  1. Всякая простая хрень. Типа пользователь, координата точки, заказ в приложении. Описал свойства и пошел дальше, не выебывайся.

    struct Point {
        var x: Double
        var y: Double
    }
    let origin = Point(x: 0, y: 0) // Вот он, родной, ноль-ноль.
    var point2 = origin // Тут, внимание, создается ПОЛНАЯ, блядь, КОПИЯ! Новый объект!
    point2.x = 5 // Меняем копию.
    // А origin.x? Ноль, ёпта! Ему вообще похуй. Спит, блядь.
  2. Предсказуемость, ебать её в сраку. С ними код ведет себя предсказуемо. Передал структуру в функцию — она там внутри может вертеть её как хочет, а твой оригинал снаружи останется нетронутым, как святой. Никаких сюрпризов, когда в одном месте поменял, а в другом всё ебнулось.

  3. Потоки, блядь. Работаешь с многопоточностью? Тут структуры — твои братья. Каждый поток получает свою копию данных и не дрочит на чужую. Безопасность, ебать её в рот.

  4. Скорость, ядрёна вошь. Для небольших данных скопировать кучу байт часто бывает быстрее, чем городить этот ваш ARC, считать ссылки, как последний бухгалтер. Просто, эффективно, внатуре.

А когда тогда брать классы, спросишь ты? Да когда тебе реально нужны их плюшки-воробушки: наследование (чтобы один класс от другого елбашился), ссылочная семантика (чтобы десять объектов тыкали в одну и ту же ячейку памяти) или лайф-цикл с деинициализатором (deinit), чтобы прикончить объект с почестями. Вот тогда — да, бери класс. А так — начинай со структуры, не мудри.