ГлавнаяБлогПочему let у класса позволяет менять свойства, а у структуры — нет
Python

Почему let у класса позволяет менять свойства, а у структуры — нет

Разбираем, почему let у класса в Swift не запрещает изменение свойств, а у структуры — запрещает. Узнайте про указатели и структуры данных.

Al
Редакция Algolitalgolit.ru
6 мин чтения23 июля 2026 г.

Почему let у класса позволяет менять свойства, а у структуры — нет?

Вы когда-нибудь создавали константный экземпляр класса (let) в Swift, меняли его свойство — и это работало? А со структурой аналогичный код выдавал ошибку? Один и тот же ключ, разное поведение. В этой статье разберёмся, почему так происходит, и запомним главное правило: let для класса фиксирует указатель, а не данные.

Краткое напоминание об указателях

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

Константа, которая не совсем константа

Вот что сбивает с толку новичков:

class Ninja {
    var name: String
    var powerLevel: Int
    init(name: String, powerLevel: Int) {
        self.name = name
        self.powerLevel = powerLevel
    }
}

let naruto = Ninja(name: "Naruto", powerLevel: 9000)
naruto.powerLevel = 9001  // ✅ Работает

Как так? naruto объявлен через let! Ответ: let naruto означает, что указатель под именем naruto зафиксирован — он всегда будет указывать на этот конкретный экземпляр Ninja. Но данные, на которые он указывает, менять можно. Изменение naruto.powerLevel не перемещает указатель, а просто меняет значение по адресу.

Что на самом деле блокирует let?

Что же тогда запрещает let? Вот это:

let naruto = Ninja(name: "Naruto", powerLevel: 9000)
naruto = Ninja(name: "Sasuke", powerLevel: 8500)  // ❌ Ошибка

Нельзя заставить naruto указывать на другого ниндзя. Указатель зафиксирован. Но менять содержимое по текущему адресу — пожалуйста.

Почему структуры работают иначе

Теперь пример со структурой:

struct AnimeCharacter {
    var name: String
    var powerLevel: Int
}

let goku = AnimeCharacter(name: "Goku", powerLevel: 9001)
goku.powerLevel = 9002  // ❌ Не компилируется

Структуры не используют указатели. let goku означает, что значение, хранящееся в goku, константно — и всё его содержимое тоже. Изменение любого поля структуры равносильно замене всей структуры целиком, а константу заменить нельзя. Если бы goku был объявлен через var, то Swift мог бы заменить всю структуру новой:

var goku = AnimeCharacter(name: "Goku", powerLevel: 9001)
goku.powerLevel = 9002  // ✅ Работает

Четыре комбинации

Рассмотрим все варианты с классами:

  1. Константный класс, константное свойство: let naruto = Ninja(...); // naruto.powerLevel = ... ❌; naruto = ... ❌ — указатель зафиксирован, свойство тоже.
  2. Константный класс, переменное свойство: let naruto = Ninja(...); naruto.powerLevel = 9001 ✅; naruto = ... ❌ — указатель зафиксирован, но данные менять можно.
  3. Переменный класс, константное свойство: var naruto = Ninja(...); // powerLevel = ... ❌; naruto = Ninja(...) ✅ — можно перенаправить указатель, но свойство не изменить.
  4. Переменный класс, переменное свойство: var naruto = Ninja(...); powerLevel = ... ✅; naruto = ... ✅ — полная гибкость.

Приятный бонус: никакого mutating

В отличие от структур, методы классов, меняющие свойства, не требуют ключевого слова mutating. Для структур mutating нужен, чтобы Swift мог проверить, можно ли вызывать метод на константной структуре. С классами проверка проще: достаточно посмотреть на объявление свойства (var или let).

Практический вывод

Запомните: let для класса фиксирует указатель, а не данные. Вы можете менять переменные свойства константного класса, но не можете перенаправить указатель на другой экземпляр. let для структуры фиксирует всё, потому что структура — это и есть данные, без промежуточного указателя.

Попробуйте прямо сейчас: откройте Playground и поэкспериментируйте с четырьмя комбинациями. Это закрепит понимание на практике.

#Swift#классы и структуры#константы#указатели#let
Al
Редакция Algolit

Пишем про алгоритмы, подготовку к собеседованиям и карьеру в IT — так, чтобы было понятно и полезно.

Хочешь закрепить знания на практике?

Решай задачи на Algolit — интерактивная платформа для обучения

Начать бесплатно →