Лекция 4 в основном теоретическая с небольшими демонстрационными примерами, рассеянными по всей Лекции и показывающими те или иные возможности Swift в действии. Это заключительная (дальше будет изучение iOS) и наиболее трудная Лекция, посвященная Swift. Но где еще вы можете увидеть такое концентрированное, логичное и понятное объяснение таких продвинутых возможностей Swift, как «множественное наследование» функциональности через протоколы protocols?
В Лекции 4 рассматриваются две основополагающие темы: протоколы protocols и замыкания (closures). Попутно мы знакомимся с тем, как организована работа со строками String, способными представлять все языки на Земле, и с тем, как «выживает» в Swift среде старый Objective-C API типа NSAttributedString, представляющий строки с атрибутами. И хотя названия созвучны String и NSAttributedString — совершенно разные вещи.
Показано, как декларируется протокол protocol. Все очень просто: список методов и переменных vars без реализации и хранения. Показано традиционное использование протокола protocol для делегирования, правда эта технология реализуется в основном протоколами старого Objective-C типа, которые отличаются от Swift протоколов тем, что могут иметь необязательные методы. У Swift протоколов protocol все методы обязательные, а технология делегирования в Swift в основном реализуется замыканиями. Затем показано использование протоколов protocol как ТИПОВ. Пока все обычно, также, как и было раньше в Objective-C.
Но дальше профессор «сажает» вас в поезд с именем «Swift протоколы». Начинается с малого, мы пытаемся сделать карту Card из игры «Концентрация» ключом словаря с эмоджи emoji, чтобы облегчить поиск. И тут выясняется, что структура struct Card должна реализовать протокол Hashable и Equatable, которые очень простые, и нам ничего не стоит добавить пару простых методов к структуре struct Card. Но, о чудо! Мы теперь работаем напрямую с картами Card в словаре, и можем сравнивать карты напрямую, что существенно улучшило наш код. Наконец-то мы начали ощущать силу протоколов при создании приложения. Это впечатляет, и наш поезд «Swift протоколы» трогается и набирает ход. Но мы продемонстрировали лишь возможность использования Swift протоколов как ограничение Generic ТИПА.
Далее профессор рассматривает протоколы Sequence и Сollection. Оказалось, что достаточно реализовать всего лишь один метод next() для последовательности Sequence, который позволяет перейти к следующему элементу, и у вас тут же появится возможность использовать цикл for in и на вас свалится «целая гора» других полезных методов. Для Сollection этот список метод еще более впечатляющий и дополняется различными методами индексации: [ ], index(offsetBy:), index(of:) и т.д.
Такое похожее на “волшебное” программирование в Swift возможно благодаря тому, что для протоколов protocols в Swift есть возможность РЕАЛИЗАЦИИ методов по умолчанию. Это делает, например, возможным выполнить для нас РЕАЛИЗАЦИЮ index (of:) для строки String, чтобы найти нужный символ, или для массива Array для нахождения элемента массива или даже для “счетного диапазона” CountableRange, хотя это и не так ценно. Поезд с именем «Swift протоколы»мчится на всех «парах».
Где вы размещаете эту реализацию, ведь протокол protocol — это просто ДЕКЛАРАЦИЯ методов без реализации?
В расширении extension вашего протокола protocol.
РЕАЛИЗАЦИЯ всех этих методов — contains(), forEach(), joined (seperator:), min (), max (), в том числе map () и filter (), которые берут в качестве аргументов замыкания (closures) — выполнена в расширении extension протокола Sequence Apple.
Кстати, На Swift форуме есть интересная статья «Conditional Conformance in the Standard Library» на этот счет.
Поезд с именем «Swift протоколы» еще ускоряете ход и мы просто «летим» вместе с Generics, Value Typing, ограничением ТИПОВ протоколами protocols, расширением extension протоколов protocols прямо к программированию, которое называется ФУНКЦИОНАЛЬНЫМ ПРОГРАММИРОВАНИЕМ. Некоторые говорят, что это своего рода эволюция ОбЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ.
Интересно то, что Swift реально и равноправно поддерживает обе эти модели программирования.
Далее API работы со строками String излагается, уже исходя исключительно из идеи РЕАЛИЗАЦИИ протоколами методов по умолчанию. Swift 4 при реализации строк String приложил героические усилия, чтобы быть насколько возможно Unicode-корректным:
Цена, которая платится за это — строки String в Swift не индексируются по Int, у них своя индексация — String.Index.
Последняя часть лекции посвящена функциям как ТИПАМ и замыканиям: их синтаксису, применению и особенностям работы с классами, которые являются Reference Type, также, как и замыкания. Существуют два ТИПА Reference Type в Swift, это классы classes и замыкания (closures). При их взаимодействии есть большая вероятность получения “циклических ссылок памяти” (memory cycles), которые нужно специальным образом прерывать.
Код демонстрационного примера для Лекции 4 находится на Github для iOS 11 и на Github для iOS 12 в папке Concentration L4.
Лекция 4 и слайды на английском языке находятся на iTunes название “4. More Swift.”
Русскоязычный неавторизованный конспект Лекции 4, хронометрированный через каждые 5 минут, и представленный в виде PDF-файла, который можно скачать и использовать offline, а также в формате Google Doc доступны на платной основе.