← Назад к вопросам

Сразу ли копируются reference type при присвоении?

1.3 Junior🔥 62 комментариев
#Язык Swift

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Копируются ли ссылочные типы при присвоении?

Нет, reference type (ссылочные типы) не копируются при присвоении в Swift. При присвоении экземпляра ссылочного типа одной переменной другой, копируется не сам объект, а лишь ссылка (указатель) на него в памяти. В результате обе переменные начинают указывать на один и тот же объект в куче (heap). Изменения, сделанные через одну переменную, немедленно отражаются при обращении через другую, поскольку они работают с общими данными.

Это фундаментальное отличие от value type (значимых типов), таких как структуры (struct) или перечисления (enum), где при присвоении создается полная независимая копия данных.

Ключевые термины и принципы

  • Reference Type: Тип, экземпляры которого передаются по ссылке. В Swift к ним относятся классы (class).
  • Value Type: Тип, экземпляры которого передаются по значению (копируются). В Swift к ним относятся структуры (struct), перечисления (enum) и все примитивные типы (например, Int, String, Bool).
  • Heap vs Stack: Экземпляры классов размещаются в динамической памяти (heap), а управление их жизненным циклом осуществляется через подсчет ссылок (ARC). Переменные-ссылки на эти объекты и экземпляры значимых типов (при определенных условиях) могут размещаться на стеке (stack).

Практическая демонстрация

Рассмотрим разницу на примере класса (ссылочный тип) и структуры (значимый тип).

// Reference Type (Class)
class UserClass {
    var name: String
    init(name: String) {
        self.name = name
    }
}

let user1 = UserClass(name: "Alice")
let user2 = user1 // Копируется только ссылка! Теперь user1 и user2 указывают на один объект.
user2.name = "Bob"
print(user1.name) // Выведет: "Bob". Данные изменились и для user1.

// Value Type (Struct)
struct UserStruct {
    var name: String
}

var structUser1 = UserStruct(name: "Alice")
var structUser2 = structUser1 // Создается полная, независимая копия данных.
structUser2.name = "Bob"
print(structUser1.name) // Выведет: "Alice". Данные structUser1 остались неизменными.

Влияние на мутабельность (изменяемость)

  • Для ссылочных типов константа (let) означает, что нельзя изменить саму ссылку (т.е. перенаправить ее на другой объект), но можно изменять свойства объекта, на который она указывает (если они объявлены как var).
  • Для значимых типов константа (let) означает полную неизменяемость всего экземпляра.
class MyClass { var value = 10 }
struct MyStruct { var value = 10 }

let myClassInstance = MyClass()
let myStructInstance = MyStruct()

myClassInstance.value = 20 // Разрешено! Меняем свойство объекта.
// myClassInstance = MyClass() // Ошибка: нельзя изменить ссылку (myClassInstance — константа).

// myStructInstance.value = 20 // Ошибка: нельзя изменить свойство, так как весь экземпляр структуры неизменяем.

Когда что использовать и почему это важно

  • Классы (Reference Type) используют, когда нужна разделяемая, изменяемая state (состояние) или наследование.
  • Структуры (Value Type) являются предпочтительным выбором в Swift по умолчанию из-за предсказуемости поведения (нет неожиданных изменений через другую ссылку), более простого управления памятью и потокобезопасности в контексте одного потока.

Вывод: При присвоении reference type копирования данных не происходит. Копируется только указатель, что приводит к созданию множества ссылок на один объект. Для создания настоящей, независимой копии объекта класса необходимо реализовать протокол NSCopying (и использовать метод copy()) или вручную написать логику инициализации нового экземпляра с теми же данными.

Сразу ли копируются reference type при присвоении? | PrepBro