Всегда ли value type в Swift копируется при присваивании?

«Всегда ли value type в Swift копируется при присваивании?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, не всегда происходит физическое копирование. Swift использует семантику копирования при присваивании, но применяет оптимизации для эффективности.

Ключевые моменты:

  1. Семантическое копирование: При присваивании (let b = a) или передаче в функцию создается новый экземпляр с семантикой независимой копии.
  2. Copy-on-Write (CoW): Для структур, хранящих данные в буфере (как Array, String, Dictionary), физическое копирование буфера откладывается до момента модификации. Это оптимизация производительности.
  3. Исключение inout: При передаче value type как inout параметра, в функцию передается ссылка на оригинальный экземпляр, а не его копия.

Примеры:

struct Point { var x = 0, y = 0 }

// 1. Семантическое копирование
var p1 = Point(x: 1, y: 2)
var p2 = p1 // p2 — семантическая копия p1
p2.x = 3    // Изменяет только p2
print(p1.x) // 1 (p1 не изменился)

// 2. Copy-on-Write на практике
var array1 = [1, 2, 3]
var array2 = array1 // Буфер данных НЕ копируется здесь (оба массива ссылаются на один буфер)
array2.append(4)    // Только теперь происходит физическое копирование буфера для array2

// 3. Передача по ссылке с inout
func translate(point: inout Point) {
    point.x += 10 // Модифицирует оригинальную переменную
}
translate(point: &p1)
print(p1.x) // 11