Интервью
November 11

Почему нельзя добавить stored property в extension к структуре или к классу?

👋 В ходе dev-скринингов часто возникает один и тот же вопрос: можно ли добавить хранимые свойства в расширения классов или структур? Ответ на него прост и однозначен: нет, нельзя.

Для наглядности рассмотрим следующий пример. Допустим, у нас есть структура Person, которая содержит только одно свойство name:

struct Person {
    var name: String
}

А теперь попробуем добавить к ней свойство age с помощью расширения:

extension Person {
    var age: Int
}

И компилятор выдаст нам ошибку:

Extensions must not contain stored properties

Это переводится как "Расширения не должны содержать хранимые свойства".

В этой статье давайте попытаемся разобраться в причинах этого ограничения и его последствиях.

Что такое хранимые и вычисляемые свойства?

Прежде чем углубляться в детали, давайте определимся с терминами.

Хранимые свойства (Stored properties) - это свойства, которые хранят свои значения. Они объявляются внутри класса или структуры и занимают место в памяти для фактического хранения данных, например:

struct Person {
    var name: String
    var age: Int
}

Вычисляемые свойства (Computed properties) - это свойства, значения которых не сохраняются напрямую. Вместо этого они вычисляются каждый раз при обращении к ним, например:

extension Person {
    var description: String {
        return "\(name), \(age) years old"
    }
}

Почему нельзя добавлять хранимые свойства в расширения?

Теперь давайте рассмотрим причины, по которым Swift не позволяет добавлять хранимые свойства в расширения.

  1. Структура памяти и инициализация. Когда вы создаете структуру или класс, Swift выделяет память под все хранимые свойства, а управление этим процессом возлагается на инициализаторы. Они управляют тем, что все свойства инициализированы перед использованием экземпляра. Если бы расширения могли добавлять хранимые свойства, это создало бы неясности и сложность в управлении памятью и инициализацией. Например, расширения могут применяться в разных местах к одному типу, и такое неконтролируемое добавление свойств подорвало бы целостность его структуры.
  2. Нарушение инкапсуляции. Инкапсуляция — это принцип, который защищает внутренние состояния объектов и избегает непредсказуемых изменений. Позволяя добавлять хранимые свойства в расширениях, мы нарушили бы этот принцип.Добавление такого свойства в расширение может разладить структуру исходного класса или структуры, создавая лишние сложности для взаимодействия с ними
  3. Управление версиями и совместимость. Подумайте: что произойдет, если вы добавите хранимое свойство в расширение внешнего класса? Если другой разработчик сделает то же самое, это может привести к конфликтам, которые сложно разрешить. Swift уже предлагает довольно строгую систему типов и управления версиями. Исключив хранимые свойства из расширений, мы упрощаем этот процесс, а также повышаем надежность и безопасность кода.
  4. Интерфейс и документация. Часто расширения используются для упорядочивания кода и добавления методов или свойств, которые имеют отношение к определенной теме.Добавление хранимых свойств в расширение может нарушить логику интерфейса и сделать код менее понятным. Четкость и предсказуемость структуры кода крайне важны для его поддерживаемости, а хранимые свойства в расширениях могут добавить путаницы.

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

👍 Если вам понравилась статья и вы нашли ее полезной, не стесняйтесь поставить лайк! Ваши оценки меня вдохновляют делиться новыми знаниями и опытом.