Почему нельзя добавить stored property в extension к структуре или к классу?
👋 В ходе dev-скринингов часто возникает один и тот же вопрос: можно ли добавить хранимые свойства в расширения классов или структур? Ответ на него прост и однозначен: нет, нельзя.
Для наглядности рассмотрим следующий пример. Допустим, у нас есть структура Person, которая содержит только одно свойство name:
struct Person { var name: String }
А теперь попробуем добавить к ней свойство age с помощью расширения:
extension Person { var age: Int }
И компилятор выдаст нам ошибку:
Это переводится как "Расширения не должны содержать хранимые свойства".
В этой статье давайте попытаемся разобраться в причинах этого ограничения и его последствиях.
Что такое хранимые и вычисляемые свойства?
Прежде чем углубляться в детали, давайте определимся с терминами.
Хранимые свойства (Stored properties) - это свойства, которые хранят свои значения. Они объявляются внутри класса или структуры и занимают место в памяти для фактического хранения данных, например:
struct Person { var name: String var age: Int }
Вычисляемые свойства (Computed properties) - это свойства, значения которых не сохраняются напрямую. Вместо этого они вычисляются каждый раз при обращении к ним, например:
extension Person { var description: String { return "\(name), \(age) years old" } }
Почему нельзя добавлять хранимые свойства в расширения?
Теперь давайте рассмотрим причины, по которым Swift не позволяет добавлять хранимые свойства в расширения.
- Структура памяти и инициализация. Когда вы создаете структуру или класс, Swift выделяет память под все хранимые свойства, а управление этим процессом возлагается на инициализаторы. Они управляют тем, что все свойства инициализированы перед использованием экземпляра. Если бы расширения могли добавлять хранимые свойства, это создало бы неясности и сложность в управлении памятью и инициализацией. Например, расширения могут применяться в разных местах к одному типу, и такое неконтролируемое добавление свойств подорвало бы целостность его структуры.
- Нарушение инкапсуляции. Инкапсуляция — это принцип, который защищает внутренние состояния объектов и избегает непредсказуемых изменений. Позволяя добавлять хранимые свойства в расширениях, мы нарушили бы этот принцип.Добавление такого свойства в расширение может разладить структуру исходного класса или структуры, создавая лишние сложности для взаимодействия с ними
- Управление версиями и совместимость. Подумайте: что произойдет, если вы добавите хранимое свойство в расширение внешнего класса? Если другой разработчик сделает то же самое, это может привести к конфликтам, которые сложно разрешить. Swift уже предлагает довольно строгую систему типов и управления версиями. Исключив хранимые свойства из расширений, мы упрощаем этот процесс, а также повышаем надежность и безопасность кода.
- Интерфейс и документация. Часто расширения используются для упорядочивания кода и добавления методов или свойств, которые имеют отношение к определенной теме.Добавление хранимых свойств в расширение может нарушить логику интерфейса и сделать код менее понятным. Четкость и предсказуемость структуры кода крайне важны для его поддерживаемости, а хранимые свойства в расширениях могут добавить путаницы.
Надеюсь, мы подробно рассмотрели, почему в Swift нельзя добавлять хранимые свойства в расширения классов и структур. Это ограничение, безусловно, имеет свои причины, и понимание этого принципа поможет вам писать более чистый и безопасный код.
👍 Если вам понравилась статья и вы нашли ее полезной, не стесняйтесь поставить лайк! Ваши оценки меня вдохновляют делиться новыми знаниями и опытом.