Подтвердить что ты не робот

Как я должен рассуждать, когда мне нужно выбирать между классом, структурой и перечислением в Swift?

Поскольку классы, структуры и перечисления имеют конструкторы, свойства и вычисленные свойства, как я должен рассуждать при выборе между ними?

4b9b3361

Ответ 1

Ответы ChristopheD и Jack Wu хороши, но я чувствую, что они не затрагивают перечисления и не пропускают их важность. Перечисления Swift являются (должны быть) полной реализацией алгебраических типов данных. Классы и структуры традиционно используются для моделирования данных в объектно-ориентированных языках, но перечисления обычно ограничиваются использованием в качестве удобного способа ограничения значения переменной ограниченным числом возможностей. Например. (C++):

enum MaritalStatus { Unmarried, Married, Divorced, WidowedOrWidowered };
MaritalStatus m = Unmarried;

Перечисления Swift могут выполнять вышеописанное, но они могут делать гораздо больше. Конечно, у Language Guide есть довольно хороший пример моделирования штрих-кода, но лучший из известных мне примеров, который действительно помогает понять точку моделирования данных с алгебраическими типами данных, - презентация Скотта Влашина: http://www.slideshare.net/ScottWlaschin/ddd-with-fsharptypesystemlondonndc2013

Вы, вероятно, выиграете, пройдя всю презентацию, но на самом деле, чтобы "понять", все, что вам нужно, это слайд 60, где он показывает, как смоделировать "метод оплаты" в типичном бизнес-приложении.

Примеры в презентации приведены на F #, но F # не так уж далек от Swift, и вы можете довольно легко отобразить их. Например, перечисление способов оплаты в Swift будет выглядеть следующим образом:

enum PaymentMethod {
    case cash // No extra data needed.
    case cheque(Int) // Cheque #.
    case card(CardType, CardNumber) // 2 pieces of extra data.
}

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

Презентация действительно начинается оттуда, и лучшая часть в том, что Swift может делать почти все, что может F # в плане моделирования данных, использования дополнительных типов и т.д.

Ответ 2

Помимо рекомендаций по практическому использованию класса, структуры и перечисления, вот сравнение, которое разъясняет способности среди них Swift Classes, Structs, Enums и Сравнение кортежей

enter image description here

Ответ 3

Я думаю, что это довольно изысканная дискуссия! Мне нравятся мысли, высказанные здесь: http://www.swift-studies.com/blog/2014/7/1/struct-enum-or-class

Там довольно много деталей и их рекомендаций. Я скопировал их резюме здесь, но это целая статья

  • Перечисления инициализируются одним из конечного числа случаев, полностью определяется их регистром и всегда должно быть действительным случаи того случая, когда экземпляр
  • Структуры следует использовать, когда не существует конечного числа допустимых экземпляров (например, перечислимых случаев) и структура также не формирует полное определение объекта, но скорее атрибут объекта
  • класс полностью определяет основной Актер в вашей объектной модели, как его атрибуты, так и его взаимодействия.

Ответ 4

Во-первых, классы являются передаваемыми по ссылке, а структу- ры - по-копии.

enums все еще особый тип, чтобы указать, ну, перечисления. Они должны использоваться так же, как и раньше.

В общем, выбор класса vs Structs не должен отличаться от предыдущего. Классы по-прежнему подходят для больших/сложных объектов, а Structs хороши для небольших изолированных объектов модели. Тот факт, что структуры имеют протоколы и такие теперь, должен просто упростить ваш код и сделать его более эффективным.

Ответ 5

Структуры имеют инициализаторы-члены (экземпляры классов не получают инициализатор по умолчанию по умолчанию)

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

let vga = Resolution(width: 640, height: 480)

что имеет прекрасный смысл, поскольку они являются типами значений (и, следовательно, immutable).

Перечисления также являются типами значений. Классы являются ссылочными типами. Никаких реальных сюрпризов здесь.

Ответ 6

Самое важное различие между классами и другими именованными типами (structs/enums):

Структуры не могут быть подклассами (или подструктурами, если можно так выразиться) ни о чем. Они также не могут быть подклассифицированы сами. Наследование полностью не соответствует структуре. То же самое касается перечислений.

Ответ 7

Как правило, вы должны использовать структуры над классами, когда данные, которые вы определяете, относительно просты, вам не нужно беспокоиться о ссылках, или вам не нужно наследовать другие свойства и методы структуры данных.

Если у вас есть данные, которые не следует изменять после инициализации, мы можем гарантировать, что во время компиляции при использовании structs.

Используйте классы для ситуаций, когда вы знаете, что идентификация объекта будет важной. Другими словами, используйте классы, в которых вы хотите, чтобы несколько областей кода указывали на один и тот же экземпляр объекта.

Используйте структуры для ситуаций, когда вы знаете, что значение объекта имеет значение. Другими словами, структуры отлично подходят для ситуаций, когда это не имеет значения, если две разные области кода относятся к тому же экземпляру копии экземпляра

Если вам нужно разделить изменчивое состояние между частями вашей программы, вы должны использовать класс.

Если вам нужно наследование или вы знаете, что хотите передать ссылки на объект вокруг, используйте класс.