Ответ
Нет, не всегда. Swift использует оптимизацию Copy-on-Write (CoW), чтобы избежать ненужных копий и повысить производительность.
Как это работает:
var originalArray = [1, 2, 3]
var copiedArray = originalArray // На этом этапе НЕТ реального копирования.
// Обе переменные ссылаются на один буфер в памяти.
copiedArray.append(4) // Только в этот момент, при первой модификации,
// происходит реальное копирование данных.
Ключевые моменты:
- Цель CoW: Отложить дорогостоящее копирование до момента, когда это действительно необходимо.
- Где применяется: Swift автоматически реализует CoW для стандартных коллекций (
Array,Dictionary,Set,String). - Для пользовательских типов: Чтобы добавить CoW в свою структуру, нужно вручную управлять ссылкой на хранилище, используя
isKnownUniquelyReferenced.
Вывод: Value-семантика гарантирует логическую независимость копий, но физическое копирование данных происходит только при модификации, благодаря CoW.
Ответ 18+ 🔞
А, ну вот, опять про эту вашу семантику значений! Давайте разберемся, а то тут народ путается, как в тёмном лесу, блядь.
Так, слушайте сюда, но не так, чтобы "слушайте сюда", а просто вникайте. Говорят: "Взял массив, присвоил другому — всё, пиздец, скопировалось, память кончилась, приложение упало!" Так вот, это, блядь, не совсем правда. Вернее, совсем не правда, если говорить про Свифт.
Swift — он не дурак, ёпта. Он хитрожопый. Он использует штуку, которая называется Copy-on-Write (CoW), что можно перевести как "копирование при записи". Суть в чём, блядь? А суть в том, чтобы не копировать овердохуища данных просто так, от нехуй делать.
Смотрите, как это выглядит в жизни:
var originalArray = [1, 2, 3] // Создали массив, окей.
var copiedArray = originalArray // А вот тут — ВНИМАНИЕ! — реального копирования НЕТУ!
В этот самый момент, блядь, оба этих массива — originalArray и copiedArray — тихо, по-пидорски, смотрят на один и тот же кусок памяти. Они как два мудака у одного холодильника — вроде каждый свой, а еда одна на двоих. Никакого физического копирования миллиона элементов не происходит! Это просто новая запись в табличке "кто на что ссылается".
И всё бы хорошо, но вот наступает момент первой модификации. Это как тот самый момент, когда один из мудаков у холодильника решает сожрать последнюю котлету.
copiedArray.append(4) // БАЦ! Вот ТОЛЬКО СЕЙЧАС, блядь!
// Swift просыпается, хватается за голову и говорит:
// "Ага, один из этих распиздяев хочет изменить общие данные!
// Щас мы это исправим!"
// И происходит настоящее, полное, всамделишное копирование данных.
// Теперь у `copiedArray` свой собственный, отдельный буфер.
Вот и вся магия, ебать мои старые костыли! Цель CoW — отложить это дорогое копирование до последнего, пока не станет ясно, что без него нихуя не обойтись.
Где это работает? Да почти везде, где надо! Swift сам, по умолчанию, так делает для своих стандартных коллекций: Array, Dictionary, Set и даже для String. Не надо ни о чём думать.
А если я свою структуру накодил? А вот тут, друзья, уже повеселее. Swift за вас CoW не сделает. Придется самим, как взрослым дядям, ебаться с управлением памятью. Надо будет внутри структуры держать ссылку на какое-то хранилище и использовать функцию isKnownUniquelyReferenced, чтобы проверять, не смотрят ли на ваши данные ещё какие-нибудь глазастые пидорасы. Если смотрят — вот тогда копируйте своё хранилище. А так — живите спокойно.
Так что вывод, блядь, какой? Value-семантика — это про логическую независимость. Для вас, как для программиста, copiedArray после присваивания — это уже отдельная сущность. Вы можете про неё так думать. Но физически, в памяти, Swift будет тянуть с созданием полной копии до последнего, пока вы не начнете её менять. Он экономист, сука, бережливый.
Вот так вот, не всегда копирование — это сразу пиздец и нагрузка. Иногда это умная оптимизация, которая работает, пока вы даже не подозреваете. Чих-пых тебя в сраку, как же это удобно!