Swift. Подробно
Покупка
Новинка
Издательство:
ДМК Пресс
Автор:
Вейн Чейрд
Перевод:
Беликов Д. А.
Год издания: 2020
Кол-во страниц: 412
Дополнительно
Вид издания:
Практическое пособие
Уровень образования:
Профессиональное образование
ISBN: 978-5-97060-780-0
Артикул: 799584.02.99
Данная книга знакомит вас с навыками, необходимыми для создания профессионального программного обеспечения для платформ Apple, таких как iOS и MacOS. Вы освоите такие мощные методы, как обобщение, эффективная обработка ошибок, протокольно-ориентированное программирование и современные шаблоны Swift. Издание рассчитано на программистов продвинутого и среднего уровней.
Тематика:
ББК:
УДК:
ОКСО:
- ВО - Бакалавриат
- 09.03.01: Информатика и вычислительная техника
- 09.03.02: Информационные системы и технологии
- 09.03.03: Прикладная информатика
ГРНТИ:
Скопировать запись
Фрагмент текстового слоя документа размещен для индексирующих роботов
Чейрд ин’т Вейн Swift. Подробно
Tjeerd in ‘t Veen Swift in Depth New York, 2019
Чейрд ин’т Вейн Swift. Подробно Москва, 2020
УДК 004.432 ББК 32.972.1 B26 B26 Чейрд ин’т Вейн Swift. Подробно / Пер. с англ. Д. А. Беликова. – М.: ДМК Пресс, 2020. – 412 с. ISBN 978-5-97060-780-0 Данная книга знакомит вас с навыками, необходимыми для создания профессионального программного обеспечения для платформ Apple, таких как iOS и MacOS. Вы освоите такие мощные методы, как обобщение, эффективная обработка ошибок, протокольно-ориентированное программирование и современные шаблоны Swift. Издание рассчитано на программистов продвинутого и среднего уровней. УДК 004.432 ББК 32.972.1 Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав Материал, изложенный в данной книге, многократно проверен. Но, поскольку вероятность технических ошибок все равно существует, издательство не может гарантировать абсолютную точность и правильность приводимых сведе ний. В связи с этимиздательство не несет ответственности за возможные ошибки, связанные с использованием книги. ISBN 978-5-97060-780-0 (рус.) ©2019 by Manning Publications Co. ISBN 978-1-61729-518-8 (анг.) © Оформление, издание, ДМК Пресс, 2020
Содержание Предисловие . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Благодарности . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Об этой книге . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Почему эта книга? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Подходит ли вам эта книга? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Чем эта книга не является . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Особый акцент на практических сценариях . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Дорожная карта . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 О коде . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Книжный форум . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Об авторе . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Об иллюстрации на обложке . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Предисловие от издательства . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Отзывы и пожелания . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Список опечаток . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Нарушение авторских прав . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Глава 1. Введение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 1.1. «Золотая середина» SWIFT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 1.2. Под поверхностью . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 1.3. Минусы Swift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 1.3.1. Стабильность ABI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 1.3.2. Строгость . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 1.3.3. Сложность протоколов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 1.3.4. Параллелизм . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 1.3.5. Отход от платформ Apple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 1.3.6. Время компиляции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 1.4. Чему вы научитесь . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 1.5. Как извлечь максимум из этой книги . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 1.6. Минимальная квалификация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 1.7. Версия Swift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 Глава 2. Моделирование данных с помощью перечислений . . . . . . . . . . . . . . . . . . . . . 37 2.1. OR в сравнении с AND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 2.1.1. Моделирование данных с помощью структуры . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 2.1.2. Превращаем структуру в перечисление . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 2.1.3. Выбор между структурами и перечислениями . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 2.2. Перечисления для полиморфизма . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 2.2.1. Полиморфизм на этапе компиляции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 2.3. Перечисления вместо создания подклассов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 2.3.1. Формирование модели для приложения Workout . . . . . . . . . . . . . . . . . . . . . . . . . 47 2.3.2. Создание суперкласса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 2.3.3. Недостатки подклассов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 2.3.4. Рефакторинг модели данных с помощью перечислений . . . . . . . . . . . . . . . . . . . 49
Содержание 2.3.5. Подклассы или перечисления – что выбрать . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 2.3.6. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 2.4. Алгебраические типы данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 2.4.1. Типы-суммы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 2.4.2. Типы-произведения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 2.4.3. Распределение суммы в перечислении . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 2.4.4. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 2.5. Более безопасное использование строк . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 2.5.1. Опасность необработанных значений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 2.5.2. Сопоставление для строк . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 2.5.3. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 2.6. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Глава 3. Написание более чистых свойств . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 3.1. Вычисляемые свойства . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 3.1.1. Моделирование упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 3.1.2. Преобразование функций в вычисляемые свойства . . . . . . . . . . . . . . . . . . . . . . . 68 3.1.3. Завершение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 3.2. Ленивые свойства . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 3.2.1. Создание учебного плана . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 3.2.2. Когда вычисляемые свойства не помогают . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 3.2.3. Использование ленивых свойств . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 3.2.4. Делаем ленивое свойство устойчивым . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 3.2.5. Изменяемые и ленивые свойства . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 3.2.6. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 3.3. Наблюдатели свойств . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 3.3.1. Обрезка пробелов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 3.3.2. Запуск наблюдателей свойств из инициализаторов . . . . . . . . . . . . . . . . . . . . . . . 81 3.3.3. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 3.4. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 Глава 4. Делаем опционалы второй натурой . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 4.1. Назначение опционалов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 4.2. Чистое извлечение значений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 4.2.1. Сопоставление для опционалов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 4.2.2. Методы извлечения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 4.2.3. Когда значение вас не интересует . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 4.3. Сокрытие переменной . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 4.3.1. Реализация протокола CustomStringConvertible . . . . . . . . . . . . . . . . . . . . . . . . . . 93 4.4. Когда опционалы запрещены . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 4.4.1. Добавление вычисляемого свойства . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 4.5. Возврат опциональных строк . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 4.6. Детальный контроль над опционалами . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.6.1. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 4.7. Откат назад, если опционал равен nil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 4.8. Упрощение опциональных перечислений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 4.8.1. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Содержание 7 4.9. Цепочки опционалов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 4.10. Ограничение опциональных логических типов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 4.10.1. Сокращение логического типа до двух состояний . . . . . . . . . . . . . . . . . . . . . . 104 4.10.2. Откат к значению true . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 4.10.3. Логический тип данных с тремя состояниями . . . . . . . . . . . . . . . . . . . . . . . . . . 105 4.10.4. Реализация протокола RawRepresentable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 4.10.5. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 4.11. Рекомендации по принудительному извлечению значения . . . . . . . . . . . . . . . . 108 4.11.1. Когда принудительное извлечение значения является «приемлемым» . . . . 109 4.11.2. Аварийный сбой со стилем . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 4.12. Приручаем неявно извлекаемые опционалы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 4.12.1. Как распознать неявно извлекаемый опционал . . . . . . . . . . . . . . . . . . . . . . . . 111 4.12.2. Неявно извлекаемые опционалы на практике . . . . . . . . . . . . . . . . . . . . . . . . . . 111 4.12.3. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 4.13. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Глава 5. Разбираемся с инициализаторами . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117 5.1. Правила инициализаторов структуры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 5.1.1. Пользовательские инициализаторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 5.1.2. Странность инициализатора структуры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 5.1.3. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 5.2. Инициализаторы и подклассы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 5.2.1. Создание суперкласса настольной игры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 5.2.2. Инициализаторы BoardGame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 5.2.3. Создание подкласса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 5.2.4. Потеря вспомогательных инициализаторов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 5.2.5. Возвращение инициализаторов суперкласса . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 5.2.6. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 5.3. Минимизация инициализаторов класса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 5.3.1. Реализация назначенного инициализатора в качестве вспомогательного с использованием ключевого слова override . . . . . . . . . . . 130 5.3.2. Деление подкласса на подклассы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 5.3.3. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 5.4. Требуемые инициализаторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 5.4.1. Фабричные методы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 5.4.2. Протоколы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 5.4.3. Когда классы являются финальными . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 5.4.4. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 5.5. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 Глава 6. Непринужденная обработка ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142 6.1. Ошибки в Swift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 6.1.1. Протокол Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 6.1.2. Генерация ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 6.1.3. Swift не показывает ошибки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 6.1.4. Сохранение среды в предсказуемом состоянии . . . . . . . . . . . . . . . . . . . . . . . . . 147
Содержание 6.1.5. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 6.2. Распространение ошибок и перехват . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 6.2.1. Распространение ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 6.2.2. Добавление технических деталей для устранения неполадок . . . . . . . . . . . . . 154 6.2.3. Централизация обработки ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 6.2.4. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 6.3. Создание симпатичных API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 6.3.1. Сбор достоверных данных в типе . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 6.3.2. Ключевое слово try? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 6.3.3. Ключевое слово try! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 6.3.4. Возвращение опционалов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 6.3.5. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 6.4. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 Глава 7. Обобщения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .168 7.1. Преимущества обобщений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 7.1.1. Создание обобщенной функции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 7.1.2. Рассмотрение обобщений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 7.1.3. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 7.2. Ограничение обобщений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 7.2.1. Нужна функция ограничения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 7.2.2. Протоколы Equatable и Comparable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 7.2.3. Ограничивать значит специализировать . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 7.2.4. Реализация протокола Comparable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 7.2.5. Ограничение в сравнении с гибкостью . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 7.3. Ряд ограничений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 7.3.1. Протокол Hashable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 7.3.2. Комбинируем ограничения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 7.3.3. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 7.4. Создание обобщенного типа . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 7.4.1. Желание совместить два типа, соответствующих протоколу Hashable . . . . . . 183 7.4.2. Создание типа Pair . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 7.4.3. Несколько обобщений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 7.4.4. Соответствие протоколу Hashable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 7.4.5. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 7.5. Обобщения и подтипы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 7.5.1. Подтипы и инвариантность . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 7.5.2. Инвариантность в Swift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 7.5.3. Универсальные типы Swift получают особые привилегии . . . . . . . . . . . . . . . . . 190 7.6. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 Глава 8. Становимся профессионалами в протокольно-ориентированном программировании . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .194 8.1. Время выполнения в сравнении со временем компиляции . . . . . . . . . . . . . . . . . . . . 195 8.1.1. Создание протокола . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 8.1.2. Обобщения в сравнении с протоколами . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Содержание 9 8.1.3. Находим компромисс . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 8.1.4. Переход ко времени выполнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 8.1.5. Выбор между временем компиляции и временем выполнения . . . . . . . . . . . . 199 8.1.6. Когда обобщение – лучший вариант . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 8.1.7. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 8.2. Зачем нужны ассоциированные типы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 8.2.1. Недостатки протоколов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 8.2.2. Попытка превратить все в протокол . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 8.2.3. Разработка обобщенного протокола . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 8.2.4. Моделирование протокола с ассоциированными типами . . . . . . . . . . . . . . . . . 206 8.2.5. Реализация протокола с ассоциированными типами . . . . . . . . . . . . . . . . . . . . . 207 8.2.6. Протоколы с ассоциированными типами в стандартной библиотеке . . . . . . . 209 8.2.7. Другие случаи использования ассоциированных типов . . . . . . . . . . . . . . . . . . 209 8.2.8. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 8.3. Передача протокола с ассоциированными типами . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 8.3.1. Использование оператора where с ассоциированными типами . . . . . . . . . . . 212 8.3.2. Типы, ограничивающие ассоциированные типы . . . . . . . . . . . . . . . . . . . . . . . . . 213 8.3.3. Очистка API и наследование протокола . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 8.3.4. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 8.4. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Глава 9. Итераторы, последовательности и коллекции . . . . . . . . . . . . . . . . . . . . . . . . .221 9.1. Итерация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 9.1.1. Циклы и метод makelterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 9.1.2. IteratorProtocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 9.1.3. Протокол Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 9.1.4. Посмотрим поближе . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 9.2. Сила Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 9.2.1. Метод filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 9.2.2. Метод forEach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 9.23. Метод enumerated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 9.2.4. Ленивая итерация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 9.2.5. Метод reduce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 9.2.6. Метод reduce into . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 9.2.7. Метод zip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 9.2.8. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 9.3. Создание обобщенной структуры данных с помощью Sequence . . . . . . . . . . . . . . . 233 9.3.1. Bag в действии . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 9.3.2. Создаем BagIterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 9.3.3. Реализация AnyIterator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 9.3.4. Реализация ExpressibleByArrayLiteral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 9.3.5. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 9.4. Протокол Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 9.4.1. Ландшафт Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 9.4.2. MutableCollection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
Содержание 9.4.3. RangeReplaceableCollection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 9.4.4. BidirectionalCollection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 9.4.5. RandomAccessCollection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 9.5. Создание коллекции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 9.5.1. Создание плана поездки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 9.5.2. Реализация Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 9.5.3. Пользовательские сабскрипты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 9.5.4. ExpressibleByDictionaryLiteral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 9.5.5. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 9.6. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 Глава 10. map, flatMap и compactMap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .255 10.1. Знакомство с map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 10.1.1. Создание конвейера с помощью метода map . . . . . . . . . . . . . . . . . . . . . . . . . . 258 10.1.2. Использование метода map для словарей . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 10.1.3. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 10.2. Последовательности . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 10.2.1. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 10.3. Использование метода map для опционалов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 10.3.1. Когда использовать метод map с опционалами . . . . . . . . . . . . . . . . . . . . . . . . . 264 10.3.2. Создание обложки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 10.3.3. Более короткий вариант нотации . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 10.3.4. Упражнение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 10.4. map – это абстракция . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 10.5. Овладеваем методом flatMap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 10.5.1. В чем преимущества flatMap? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 10.5.2. Когда метод map не подходит . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 10.5.3. Борьба с пирамидой гибели . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 10.5.4. Использование метода flatMap с опционалом . . . . . . . . . . . . . . . . . . . . . . . . . . 275 10.6. flatMap и коллекции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 10.6.1. flatMap и строки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 10.6.2. Сочетание flatMap и map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 10.6.3. compactMap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 10.6.4. Вложенность или цепочки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 10.6.5. Упражнения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 10.7. В заключение . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Глава 11. Асинхронная обработка ошибок с помощью типа Result . . . . . . . . . . . . . . .290 11.1. Зачем использовать тип Result? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 11.1.1. Как раздобыть Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 11.1.2. Result похож на Optional, но с изюминкой . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 11.1.3. Преимущества Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 11.1.4. Создание API с использованием типа Result . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 11.1.5. Из Cocoa Touch в Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 11.2. Распространение Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 11.2.1. Создание псевдонимов типов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299