Этот вопрос должен занимать мысли каждого разработчика при написании кода, потому что это важно. Хотя классы и структуры во многом похожи, детали имеют значение. Есть одна деталь, которая, возможно, является самым важным различием. Это то, что классы являются ссылочными типами, а структуры - типами значений. Что именно это означает?
Классы (classes)
Классы являются ссылочными типами, что означает, что когда передается объект класса, то передаваемое является ссылкой на исходное место в памяти для этого объекта. Это означает, что когда я обновляю значение переданного объекта, значения исходного объекта также будут обновлены, поскольку они оба ссылаются на один и тот же объект. Приведенный ниже код иллюстрирует именно этот процесс:
Структуры (structs)
Как упоминалось выше, структуры считаются типами значений. Это означает, что при передаче структур создается копия объекта, а не ссылка. Таким образом, если я передаю структуру в функцию, а затем изменяю значения структуры, исходная структура не изменится. Ниже приведен пример этого:
Когда стоит использовать классы, а когда структуры?
Основываясь на вышеизложенных знаниях, как мы можем принять решение? Как команда разработчиков языка Swift определилась с базовыми типами?
Давайте сначала рассмотрим Int. Он объявлен как структура. Почему? Данные, которые он представляет, одинаковы, независимо от того, скопированы они или нет. Если у меня есть два Integer с одинаковым значением, они должны быть равны друг другу, и это нормально. Мы этого ожидаем. А как насчет строки? То же самое относится и к строке. Значение двух строк может быть одинаковым, и это будет означать одно и то же, скопировано оно или нет. Это относится и к типам Double, Array и Dictionary.
Как вы думаете, какие типы объявлены как классы? UIView - это класс. Почему? Давайте подумаем, если в памяти есть два объекта UIView, то они представляют собой два уникальных объекта в иерархии представлений. Поэтому, если мы будем передавать эти представления, нам нужно будет хранить ссылки на них, потому что каждый из них уникален. Они не являются взаимозаменяемыми.
Ответ на этот вопрос сводится к следующему: Как используются данные?
Другие соображения
При выборе между классом и структурой необходимо учитывать некоторые другие моменты. Компания Apple написала статью с некоторыми общими правилами. Я рекомендую вам прочитать ее, но здесь приведены несколько пунктов, резюмирующих статью:
- По умолчанию используется структура. Структуры более оптимизированы, чем классы, а также являются потокобезопасными. Благодаря этому, структуры автоматически устраняют весь спектр ошибок.
- Используйте классы, когда код должен использоваться в Objective-C. Структуры Swift не существуют в Objective-C.
- Используйте классы при управлении идентификацией. Это общий случай с локальными базами данных, работой с файлами или сетевыми соединениями.
- Используйте структуры, когда вы не контролируете идентичность. Чаще всего это происходит при моделировании данных с сервера. Если объект имеет идентификатор, вы не контролируете, как этот идентификатор был сгенерирован.
- Хотя структуры не могут наследоваться от других структур, они могут наследовать протоколы. Используйте наследование протоколов, когда это возможно, чтобы можно было использовать структуры.
Резюме
Различия между классами и структурами могут показаться незначительными, но эти различия весьма обширны. Знание различий жизненно важно для создания и правильного сопровождения кода.
Эта заметка является переводом оригинальной статьи Пола Онила When should I use a class vs a struct?
#Swift #ios