В Swift типы-значения (struct, enum, tuple) обладают так называемой value semantics: при передаче или присваивании переменной копируется всё содержимое – создаётся независимый экземпляр. Это позволяет избежать ряда сложностей с shared state, характерных для reference-типа (class).
Однако для оптимизации памяти коллекции (например Array, Dictionary, Set) используют стратегию copy-on-write: копирование происходит только тогда, когда один из экземпляров изменяется.
Пример:
var a = [1, 2, 3] var b = a b.append(4) print(a) // [1, 2, 3] print(b) // [1, 2, 3, 4]
Здесь массив a не изменится — хотя изначально был общий storage, при изменении b Swift сделает отдельную копию данных.
Важно помнить: если структура содержит reference-type (например класс), value semantics применимо только к самой структуре, а не к вложенным ссылочным объектам.
Изменится ли содержимое массива, если мы передадим его в функцию и внутри этой функции его отредактируем? Объясните разницу между поведением struct и class.
Ответ с примером:
func mutate(_ arr: inout [Int]) { arr.append(100) } var source = [1, 2] mutate(&source) print(source) // [1, 2, 100]
Если не передавать по inout, копирование произойдет автоматически при первом изменении внутри функции, и исходный массив не поменяется. Для classes копирования не происходит – изменится исходный объект всегда.
История
Разработчики складывали reference-объекты в массив структур (struct), ожидая, что изменение через одну структуру не затронет другие экземпляры. На деле, меняя ссылочные объекты в одном месте, они неожиданно менялись сразу везде (shared state).
История
В командном проекте пытались добиться защиты от race condition копированием коллекций при каждом обращении. Это вызвало непредвиденные расходы памяти и падение производительности при работе с большими массивами.
История
Молодой разработчик пытался отслеживать изменения в массиве, из-за чего передавал его по inout в несколько функций-обработчиков одновременно. Порядок модификаций становился неочевиден, и это привело к потоконебезопасным изменениями, багам и ошибкам синхронизации.