В чем разница между копированием массива и структуры в Swift?

Ответ

Разница обусловлена семантикой типов: классы (и массивы, если они содержат ссылочные типы) — ссылочные, структуры — значимые.

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

  1. Копирование класса/массива (ссылочных типов) передает ссылку на тот же экземпляр в памяти.
  2. Копирование структуры создает новую, независимую копию данных.

Пример:

// Класс (ссылочный тип)
class MyClass { var value = 10 }
let obj1 = MyClass()
let obj2 = obj1          // Копируется ссылка
obj2.value = 20
print(obj1.value)        // 20 — изменение затронуло оба "объекта"

// Структура (значимый тип)
struct MyStruct { var value = 10 }
var struct1 = MyStruct()
var struct2 = struct1    // Создается полная копия данных
struct2.value = 20
print(struct1.value)     // 10 — исходная структура не изменилась

Важно: Массивы в Swift (например, Array<Int>) сами являются структурами и используют механизм copy-on-write для оптимизации: реальное копирование происходит только при изменении.

Ответ 18+ 🔞

О, слушай, вот это реально важная тема, а то многие путаются, как сука в тумане. Сейчас разложу по полочкам, чтобы на всю жизнь запомнил.

Вот смотри, вся соль в том, где эта твоя переменная живёт. Есть два лагеря:

  1. Ссылочные типы (классы, да некоторые массивы) — это как адрес на бумажке. Ты копируешь бумажку — у тебя теперь два листочка с одним и тем же адресом. Приходишь по адресу — там один и тот же дом, одна квартира. Поменял обои в этой квартире — всем, у кого такой же адресок, пизда, новые обои.
  2. Значимые типы (структуры, энамы, кортежи) — это как если бы ты скопировал не адрес, а сам дом, кирпичик к кирпичику, и поставил его на соседний участок. Покрасил свой новый дом в зелёный — старому-то соседу похуй, у него свой, отдельный, в синем остался.

Пример, чтобы мозг не взорвался:

// Класс — это ссылочный тип, сука
class MyClass { var value = 10 }
let obj1 = MyClass() // Построили одну квартиру
let obj2 = obj1      // Скопировали только бумажку с её адресом! Это НЕ новый дом!
obj2.value = 20      // Зашли по адресу и обои поменяли
print(obj1.value)    // 20 — ОПА! А в первой "переменной" тоже 20! Потому что это одна и та же квартира, ёпта!

// Структура — это значимый тип
struct MyStruct { var value = 10 }
var struct1 = MyStruct() // Построили один дом
var struct2 = struct1    // ВЖУХ! Создали ПОЛНУЮ КОПИЮ всего дома на новом месте!
struct2.value = 20       // Покрасили копию в другой цвет
print(struct1.value)     // 10 — Исходный дом как был, так и остался. Ничего ему не сделалось.

А теперь про массивы, тут прикол. Сам массив (Array) — это структура, значимый тип, казалось бы. Но если в нём лежат классы (ссылки), то копируется массив-оболочка, а ссылки внутри — те же самые. А если в нём примитивы (типа Int), то работает магия copy-on-write: пока ты не начал менять массив, копия — чистая формальность, чтоб память не жрать. А как только полез что-то менять — тут же создаётся настоящая, отдельная копия данных. Хитро, блядь, придумано.

Короче, запомни: хочешь, чтобы у каждой сущности была своя, независимая жизнь — структура. Хочешь, чтобы все тыкали в один и тот же объект и меняли его — класс. И не ебись.