customstringconvertible swift что это

Swift 5: полезные протоколы, чтобы писать как профессионал

Вы знаете, какая это пустая трата времени, если вы пишете код с нуля и позже обнаруживаете, что Swift уже предоставляет встроенное решение. Использование протоколов часто решает эту проблему, а также делает ваш код более чистым и эффективным.

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

1. CaseIterable

Протокол CaseIterable позволяет получать все значения типа. Давайте посмотрим на примере.

Без CaseIterable:

С CaseIterable:

2. CustomStringConvertible

Не всем нравится описание по умолчанию для каждого объекта. Иногда мы хотим дать объекту более удобное описание только для чтения и распознавания.

Без CustomStringConvertible:

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

С CustomStringConvertible:

3. IteratorProtocol

Без IteratorProtocol:

С IteratorProtocol:

Функция makeIterator() возвращает объект, наследующий протокол IteratorProtocol. Мы можем использовать функцию next() для получения следующего значения без необходимости отслеживать текущий индекс. Помните, что функция next() возвращает необязательное значение.

Вывод

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

Источник

Создание собственной коллекции с протоколами в Swift

Создание собственной коллекции с протоколами в Swift

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

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

В этом туториале вы узнаете как:

Заметка

Этот туториал направлен на работу с Swift 5.0. Предыдущие версии не будут компилироваться из-за серьезных изменений в стандартной библиотеке Swift.

Приступим к работе

Начните с загрузки материалов проекта. Затем откройте файл Bag.playground в папке starter.

Заметка

Если вам будет так удобнее, вы можете создать свой собственный Xcode Playground, удалив весь код, чтобы начать с нуля.

Создание структуры Bag

Добавьте следующий код:

Приведем аналогию со списком покупок в магазине. Если нам нужно, например, взять с собой две бутылки воды, то вы не будете писать “бутылка воды” дважды, вместо этого, вы напишете “2 бутылки воды”.

Чтобы смоделировать это, добавьте следующие свойства Bag :

Добавим методы редактирования

Добавление метода add

Добавьте следующий метод под только что добавленными в код свойствами:

Давайте разберемся, что делают эти свойства:

Заметка

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

Реализация метода Remove

Добавьте следующее после add(_:occurrences:) :

Давайте разберем, как он работает:

Однако, не всё потеряно. Swift предоставляет инструменты, необходимые для преобразования Bag в коллекцию. Вам нужно лишь соответствовать некоторым протоколам.

Соответствие протоколам

Вот простой пример. В настоящее время объекты Bag предоставляют мало информации на боковой панели результатов.

Добавьте следующий код в конец Playground`а (вне структуры), чтобы увидеть Bag в действии:

Затем нажмите Command-Shift-Enter, чтобы начать выполнение.

Соответствие CustomStringConvertible

К счастью, Swift предоставляет протокол CustomStringConvertible для этой ситуации. Добавьте следующее сразу после закрывающей скобки Bag :

Нажмите Command-Shift-Enter, чтобы запустить проект.

Взгляните на недавно улучшенную отладочную информацию для shoppingCart :

Вы находитесь на верном пути, поскольку создаете мощные типы коллекций, которые выглядят нативными. Далее идет инициализация.

Создание инициализаторов

Добавьте следующий код в конец Playground`а, но обратите внимание, что он еще не будет компилироваться:

Добавьте следующие методы чуть ниже totalCount внутри реализации Bag :

Рассмотрим то, что только что добавили:

Нажмите Command-Shift-Enter чтобы запустить проект еще раз. Обратите внимание, что код, который вы добавили в нижней части ранее, теперь работает.

Инициализация Коллекций

Чтобы избежать этого, Swift предоставляет два протокола, которые позволяют инициализировать литералы последовательностей. Литералы дают вам сокращенный способ записи данных без детального создания объекта.

Чтобы увидеть это, сначала добавьте следующий код в конец вашего Playground`а:

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

Теперь, чтобы заставить их работать, добавьте следующие два расширения чуть ниже расширения CustomStringConvertible :

Понимание кастомных коллекций

Применение Non-destructive итераций

Узнайте больше, прочитав документацию от Apple по протоколу Collection.

Соответствие протоколу Sequence

Наиболее распространенным действием, выполняемым c коллекциями, является перебор ее элементов. Например, добавьте в конец Playground`а следующее:

Нужно это исправить.

Соответствие Sequence

Добавьте следующее сразу после ExpressibleByDictionaryLiteral :

Теперь вы можете перебирать каждый элемент Bag и получать подсчет для каждого объекта. Добавьте следующее в конец Playground`а после предыдущего цикла for-in:

Нажмите Command-Shift-Enter, чтобы запустить проект. Откройте консоль Playground`а, и вы увидите распечатку элементов и их количество в последовательности.

Рассмотрим преимущества Sequence

Нажмите Command-Shift-Enter, чтобы запустить проект и посмотреть на это в действии.

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

Улучшаем Sequence

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

Замените реализацию расширения Sequence следующей:

В этом расширении для Sequence вы:

Нажмите Command-Shift-Enter для запуска. Вы заметите пару ошибок:

Для того, чтобы исправить ошибки, поменяйте key и value на element и count соответственно. Запустите, и ваши prediction блоки пройдут так же, как и раньше.

Читайте также:  с именем какого князя связана победа на куликовом поле определите

Соответствие протоколу Collection

Осталось совсем немного деталей, и вы получите рабочую коллекцию.

Добавьте следующий код сразу после расширения Sequence :

Это довольно просто. Смотрите:

Просто добавив эти свойства и методы, вы создали полностью рабочую коллекцию!

Протестируем вашу коллекцию

Добавьте следующий код в конец Playground`а, чтобы протестировать некоторые новые функции:

Снова запустите. Потрясающе!

Уже хорошо, но можно еще лучше!

Улучшаем Collection

Пользователям Bag нужно использовать объекты DictionaryIndex для доступа к элементам в коллекции.

Вы можете легко исправить это. Добавьте следующее после расширения Collection :

В коде описанном выше вы:

Добавьте следующее расширение сразу после BagIndex :

Обновление BagIndex

Каждый комментарий отмечает некоторые изменения. Вот, что они собой представляют:

Вот и все! Пользователи снова ничего не знают о том, как вы храните данные. У вас также есть потенциал для гораздо большего контроля над индексными объектами.

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

Использование Slice

Чтобы увидеть, как это работает, добавьте следующий код в конец Playground`а:

Запустите снова. В приведенном выше коде вы:

Заметка

Поздравляю! Теперь вы профессионал в “коллекционировании”!

Источник

Использование Классов, Структур и Перечислений

Использование Классов, Структур и Перечислений

Возвращаясь во времена, когда был только Objective-C, инкапсуляция была ограничена работой с классами. Тем не менее, на современных iOS и в программировании для Mac есть три варианта: в Swift есть enums (перечисления или энумы), structs (структуры) и classes (классы).

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

Цель данного туториала в следующем:

Данное руководство предполагает, что вы уже немного знакомы со Swift и объектно-ориентированным программированием.

Все о типах

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

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

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

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

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

Есть, конечно, еще и Bool, Int, UInt, Float, Double, Character, String, Array, Set, Dictionary, Optional и др., о которых можно подумать как об основных типах. Тем не менее, они фактически построены из именованных типов и являются частью стандартной библиотеки Swift.

Этот туториал акцентирует внимание на так называемых именованных типах моделей, которые состоят из enum, struct и class.

Фигуры с Scalable Vector Graphics (SVG) (Масштабируемой Векторной Графикой)

В качестве примера, вы будете строить безопасный, быстрый и простой фреймфорк для рендера фигур SVG.

SVG является векторным форматом изображений на основе XML для 2D-графики. Спецификация, разработанная W3C в 1999 году, открытого стандарта. (https://developer.mozilla.org/en-US/docs/Web/SVG)

Приступим

Создайте новый плейграунд в Xcode ( File\New\Playground…), назовите его Shapes и выберите платформу OS X. Нажмите Next, чтобы выбрать папку, где сохраните проект, а затем Create для сохранения файла. Очистите полностью файл, а затем вставьте следующее:

Нашей задачей является возможность отрисовки фигур формата XML :

Поверьте, ответ в браузере или во view WebKit выглядит лучше. :]

Нам нужен способ для отображения цвета. SVG использует тип цвета CSS3, который может быть указан в качестве имени, RGB или HSL. Полную спецификацию можно найти здесь: http://www.w3.org/TR/css3-color/.

Чтобы использовать цвет в SVG, вы определяете его как атрибут части вашего рисунка. Например, fill = ‘Gray’. Чтобы реализовать это в Swift, то можно просто использовать let fill = «Gray».

Использовать String легко и продуктивно, но есть недостатки:

Использование пользовательского типа решит эту проблему. Если вы пришли из Cocoa Touch, вам может прийти в голову реализовать инкапсулированный класс как UIColor. И хотя использование этого класса может и сработать, но Swift дает больше возможностей для определения модели.

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

Как вариант можно его реализовать вот так:

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

На перечисления, которые явно указывают тип хранения, ссылаются как на RawRepresentable, потому что они автоматически принимают протокол RawRepresentable.

Таким образом, вы можете указать тип ColorName как String и присвоить значение каждому конкретному кейсу, например, вот так:

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

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

Добавьте следующий код в конец вашего плейграунда:

Теперь у вас есть пользовательский тип первого класса и все, что с ним связано. Например,

Связанные значения

ColorName подходит для именованного цвета, но я думаю вы помните, что CSS цвета имеют несколько вариантов отображения: именованные, RGB, HSL и другие. Как же их смоделировать?

Перечисления в Swift прекрасно подходят для моделирования того, что имеет одно из ряда вариантов отображения, например цвет CSS, и каждый кейс перечислений может быть объединен со своими собственными данными. Эти данные называются associated values (связанные значения).

Определите цвет CSSColor, используя перечисление, добавив следующее в ваш плейграунд:

Этим определением, вы придаете модели CSSColor один из двух кейсов.

Обратите внимание, что мы для краткости опускаем RGBA, HSL и HSLA кейсы.

Читайте также:  dmg file чем открыть

Протоколы и методы с перечислениями

Вы хотите иметь возможность напечатать несколько экземпляров CSSColor.

В Swift, перечисления, так же как и другие именованные типы, могут реализовывать протоколы. В частности, ваш тип может волшебным образом начать работать с функцией print, приняв протокол CustomStringConvertible.

Ключом к взаимодействию со стандартной библиотекой Swift является принятие стандартных протоколов библиотеки.

Добавьте следующее расширение для CSSColor в вашем плейграунде:

Это заставит CSSColor соответствовать CustomStringConvertible. И это как раз то, что сообщает Swift, что наш тип, CSSColor, может быть преобразован в строку, а вот как он должен быть преобразован мы определяем в вычисляемом свойстве description.

В этой реализации, self прогоняем через оператор switch, для того, чтобы определить, является ли базовая модель именованным или RGB типом. В каждом случае вы преобразуете цвет в требуемый формат строки для этого кейса. Именованный кейс просто возвращает имя строки, в то время как в RGB кейс возвращает красный, зеленый и синий цвет в требуемом формате.

Добавьте следующее в ваш плейграунд:

Все типы проверены и во время компиляции выходит proven correct, но так не будет происходить, если вы используете только значения типа String для отображения цветов.

Заметка

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

Такой стиль расширения хорош, потому что он делает то, что вы определяете для того, чтобы явно соответствовать данному протоколу. В случае с CustomStringConvertible, вам нужно реализовать геттер для строкового свойства description.

Инициализаторы с перечислениями

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

Добавьте это расширение в ваш плейграунд:

Добавьте следующее в плейграунд:

Пространства имен с перечислениями

Именованные типы могут выступать в качестве пространства имен для соблюдения организованности и сведения сложности к минимуму. Вы создали ColorName и CSSColor, и все же ColorName будет использоваться только в контексте CSSColor.

Но ведь было бы здорово, если бы вы могли скрывать ColorName внутри модели CSSColor?

А ведь вы можете! Удалите ColorName из вашего плейграуда и замените его следующим кодом:

Это переместит ColorName в расширение CSSColor. Теперь ColorName спрятан, а внутренний тип определен как CSSColor.

Заметка

Одной из главных особенностей Swift является то, что порядок объявления, как правило, не имеет значения. Компилятор сканирует файл несколько раз и находит объявления без необходимости их упорядочивания, как это происходит при работе с C / C ++ / Objective-C.

Тем не менее, если вы получаете сообщение об ошибке в вашем плейграунде о том, что ColorName необъявленного типа, переместите расширение чуть ниже вашего определения перечислений CSSColor, чтобы устранить ошибку плейграунда.

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

Перечисления могут быть созданы в виде чистого пространства имен, которые пользователи не смогут случайно создать, используя экземпляр. Например, вам скоро понадобится математическая константа pi, для выполнения некоторых вычислений. И пока вы будете использовать фреймворк Foundation и его M_PI, параллельно вы будете определять свою собственную константу, для того, чтобы сохранить все на столько портативным, насколько это возможно. (Вот и мы и пришли к Arduino микро-контроллеру!)

Добавьте следующий код в конец вашего плейграунда:

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

Объявив pi как статическую константу, вам не нужно создавать экземпляр энума. Всякий раз, когда вам нужно значение pi, вы можете просто использовать Math.pi, а не вспоминать все эти цифры!

Переоценка перечислений (энумов)

Перечисления гораздо более мощный инструмент в Swift, чем в других языках, таких как C или Objective-C. Как вы уже видели, вы можете расширять их, создавать собственные методы инициализатора, обеспечивать пространство имен и инкапсулировать смежные операции.

С другой стороны, если вы хотите, чтобы CSSColor был расширяемым пользователем до других моделей цветового пространства, не определенных в спецификации W3C, то перечисление не является предпочтительной абстракцией.

Которая, кстати, приведет вас к следующему именованному типу модели в Swift, Structures (структурам). :]

Использование структур

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

Новые кейсы enum не смогут быть добавлены позже в расширение. Значит остается либо class или struct.

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

Протокол определяет, что значит Drawable. У него есть метод draw, который рисует то, что называется DrawingContext.

Вы готовы определить круг, который принимает протокол Drawable. Добавьте это в ваш плейграунд:

В структуре вы группируете свойства хранения. Здесь вы реализовали следующие свойства:

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

Ссылочный тип и тип значения

Типы значений работают как отдельные и отличные сущности.

Квинтэссенциальный тип значения является Int, так как именно он так работает в большинстве языков программирования. Если вы хотите знать, как именно работает тип значения, то задайте вопрос: «Что бы сделал Int?» Например:

Для Int:

Для Circle (определенный с помощью структур):

Если вы сделали свой круг из типа класса, он получил бы ссылочную семантику. Это означает, что он ссылается на основной общий объект.

Для Circle, определенного с помощью класса:

Модель Прямоугольника

Добавьте следующий код в плейграунд для того, чтобы продолжить создание вашей библиотеки с рисунками, создав тип прямоугольника:

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

Circle и Rectangle принимают протокол Drawable. Они переносят фактическую работу на что-то, что соответствует протоколу DrawingContext.

Теперь пришло время сделать конкретную модель, которая нарисует изображение в SVG стиле. Добавьте это в ваш плейграунд:

Читайте также:  что делать если кисты в щитовидке

И, наконец, вам нужен тип документа, который сможет содержать множество Drawable объектов, поэтому добавьте следующее в ваш плейграунд:

Покажите мне немного SVG

Как насчет того, чтобы наконец-то нарисовать SVG? Добавим следующее в плейграунд:

Это создаст круг и прямоугольник по умолчанию и поместит их в документ, а затем он выведет XML.

Теперь давайте сделаем наглядным SVG. Добавьте следующие строки в конце плейграунда:

Это небольшой фокус плейграунда и он настраивает веб-просмотр для просмотра SVG. Нажмите Command-Option-Return, чтобы увидеть это веб-вью в assistant editor.

Использование классов

До сих пор вы использовали комбинацию структур (типов значения) и протоколы для реализации Drawable моделей.

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

Чтобы сделать объектно-ориентированное программирование более безопасным, Swift ввел ключевое слово override. Это нужно для того, чтобы вы, программисты, понимали, когда вы что-то переопределяете.

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

Тем не менее, в этом объектно-ориентированном подходе есть свои недостатки.

Первую проблему вы заметите в реализации базового класса рисунка. Shape хочет избежать неправильного использования, поэтому он вызывает fatalError() и предупреждает производные классы, что они должны переопределить этот метод.

К сожалению, эта проверка происходит во время выполнения, а не во время компиляции.

Во-вторых, классам Circle и Rectangle приходится иметь дело с инициализацией данных базового класса. Несмотря на то, что это относительно просто, инициализация класса может осложниться для гарантии корректной работы кода.

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

Например, предположим, что вы хотите добавить Drawable тип Line. Для того чтобы работать с существующей системой, она должна наследовать от Shape, что немного неправильно.

Кроме того, ваш класс Line должен инициализировать свойство базового класса fillColor, и что не имеет смысла для линии.

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

Наконец, классы имеют эталонную семантику, которая обсуждалась ранее. В то время как Automatic Reference Counting (ARC) большую часть времени заботится о процессах, вы должны быть осторожны с тем, чтобы не ввести зацикленные ссылки, или в конечном счете все закончится утечкой памяти.

Если вы добавляете такую ​​же фигуру в массив фигур, то вы можете удивиться, изменив цвет одной фигуры на красный, что другая также вдруг изменится.

Для чего вообще использовать класс?

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

Для начинающих, они позволяют принимать прошедшие огонь и воду фреймворки, такие как Cocoa и Cocoa Touch.

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

Вычисляемые Свойства

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

Предположим, что вы хотите добавить геттер и сеттер диаметра вашей модели Circle. Это легко реализовать через существующее свойство radius.

Добавьте следующий код в конец вашего плейграунда:

Это реализует новое вычисляемое свойство, которое основывается исключительно на радиусе. Когда вы получаете диаметр, он возвращает удвоенный радиус. При установке диаметра, он устанавливает радиус, деленный на 2. Проще простого!

Добавьте следующий код в только что добавленное расширение круга:

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

Например, добавьте следующее в расширение Circle:

Этим мы пытаемся определить метод shift() на circle, который будет перемещать круг в пространстве. т.е. изменять центральную точку.

Но тогда выбрасывается следующее сообщение об ошибке на две строки, которые инкрементируют свойства center.x и center.y.

Мы можем это исправить путем добавления ключевого слова mutating, например, вот так:

Это сообщает Swift, что все OK, и что ваша функция меняет (мутирует) структуру.

Ретроактивное моделирование

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

Вот случай использования: Предположим, вы являетесь пользователем кода SVG, и хотите добавить свойства area и perimeter вашему Rectangle так же, как у Circle.

Давайте посмотрим, как это работает:

Ранее вы использовали extension для добавления методов к уже существующей модели, а теперь, вы будете формулировать эти методы в новом протоколе.

Добавьте это в ваш плейграунд:

Это даст вам официальный протокол.

Далее, вы сообщаете кругу и прямоугольнику принять этот протокол “задним числом”, добавив следующую строку в ваш плейграунд:

Кроме того, вы можете определить функцию, которая, например, вычисляет общий периметр моделей массива (любого сочетания структур, перечислений, классов), которые принимают протокол ClosedShapeType.

Добавим следующий код:

Здесь используется reduce для вычисления суммы периметров.

У всех трех есть основные сходства: они обеспечивают инкапсуляцию, могут иметь методы инициализатора, могут иметь вычисляемые свойства, реализовывать протоколы, и они могут быть смоделированы «задним числом».

Тем не менее, они имеют и существенные различия.

Перечисления являются типами значений (value types) с набором кейсов, где каждый кейс может иметь различные соответствующие значения (associated values). Каждое значение типа перечисления представляет собой единственный кейс, как это определено в перечислении. У них не может быть свойств хранения.

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

Но в отличие от структур и перечислений, классы используют ссылки, aka sharing, семантику.

Что дальше?

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

Источник

Сказочный портал