Cihat Gündüz
13 января
Одним из побочных эффектов захвата Твиттера Илоном Маском стало то, что уже в этом месяце провайдер, на котором размещался данный журнал - закрылся. А пока я все еще путешествую по Японии (к сожалению, осталось всего несколько дней 😔), мне пришлось найти нового провайдера и все мигрировать, поэтому этот выпуск выходит так запоздало. И именно поэтому дизайн и автор этого журнала будут выглядеть по-другому, если вы читаете это в виде рассылки по электронной почте.
Вот новая ссылка на журнал: https://swiftevolution.substack.com
Если вы предпочитаете программу для чтения RSS , используйте эту ссылку: https://swiftevolution.substack.com/feed
Я намеренно пропустил ноябрьский выпуск, так как не было достаточно интересных новостей, которые можно было бы осветить с точки зрения разработчиков приложений. Но в декабре вышло несколько интересных публикации, а в январе было аж две статьи, о которых я расскажу в следующем выпуске. Я также решил перенести обзор еще одной статьи в следующий выпуск, иначе этот текст стал бы слишком длинным.
Без лишних слов, давайте выясним что произошло в ноябре/декабре!
Акцептованные рекомендации
Были приняты следующие правки, предложенные ранее :
Предложения находящиеся на рассмотрении/пересмотре/ожидании
Вы по-прежнему можете оставлять отзывы на предложенные правки и предложения. Текущий процент отказов составляет <10%, поэтому они, скорее всего, будут акцептованы. Ревизии встречаются чаще.
SE-0378: Аутентификация реестра пакетов
Ссылки: документ с предложением 📝 | Обзор 🧵
Прежде чем мы перейдем к новостям об этом предложении, позвольте мне сначала пояснить, что такое «реестр пакетов», поскольку этот новостная рассылка была запущен после того, как они были приняты в Swift, и поэтому я еще не рассматривал и не освещал их. SE-0292: Служба реестра пакетов, которая только недавно появилась в Swift 5.7 (в Xcode 14), добавляет альтернативный способ объявления зависимостей пакетов при использовании SwiftPM. Вместо того, чтобы использовать Git и его действия, такие как clone или checkout для получения зависимостей с помощью SwiftPM, идея реестра пакетов состоит в том, чтобы определить RESTful API в качестве альтернативы получению через Git. Предоставляемый реестром пакетов опыт очень похож на API и имеет преимущества в производительности и надежности по сравнению с использованием Git для поиска зависимостей и выборки. Хорошая новость для разработчиков приложений или фреймворков заключается в том, что эти детали скрыты SwiftPM и службами реестра, которые их реализуют. Если вы не планируете внедрять такую службу реестра самостоятельно (что может иметь смысл для крупных компаний, в таком случае ознакомьтесь с полным описанием предложений!), все, что вам нужно знать, это:
Благодаря SE-0292, начиная с Swift 5.7, всякий раз, когда вы добавляете зависимость к своим проектам с помощью SwiftPM, вы можете принять решение указать или URL-адрес GitHub (что всегда было возможно), либо, в качестве альтернативы, предоставить своего рода идентификатор для проекта, состоящий из scope и name пакета, например, что-то вроде FlineDev/HandySwift. В этом примере FlineDev — это имя моей организации в GitHub, которое служит диапазоном работ и HandySwift (библиотека, в которую я извлекаю свой многократно используемый код Swift) однозначно идентифицирует вспомогательную библиотеку в рамках этого диапазона. Теперь SwiftPM будет искать реестры пакетов, в которые вы выполнили вход, чтобы найти и загрузить версию моей HandySwift библиотеки.
Да, вы правильно прочитали: сначала вам нужно войти в реестр пакетов. Кроме того, библиотека должна быть доступна через этот реестр. Apple объявила, что они стремятся (эффективно) заменить текущее управление зависимостями на основе Git на перманентное решение на основе реестра. Они планируют сотрудничать с уже ставшим полезным проектом Swift Package Index (веб-сайт, который помогает находить пакеты, размещает документацию и многое другое), что Дейв Вервер, один из основных участников проекта, подтвердил в своем журнале. Это, вероятно, станет универсальным местом для всех разработчиков Swift, чтобы получить библиотеки с открытым исходным кодом, (я могу только догадываться) и может быть когда-нибудь в бедующем, если будет популярным, сможет даже стать сервером по умолчанию, встроенным в SwiftPM, подобно CocoaPods (или RubyGems для Ruby/ PyPI для Python/ npm для JavaScript). Но давайте посмотрим, как будут развиваться события.
Из нового, что привносит это предложение — это еще один метод аутентификации: в настоящее время поддерживается только базовая аутентификация , что ограничивает некоторые взаимодействия. Это предложение направлено на добавление аутентификации с помощью токена и исправление некоторых аспектов безопасности текущей системы аутентификации (отсутствие файла аутентификации на уровне проекта и использование цепочки ключей в macOS). Я рад слышать, что мы, наконец, приближаемся к более быстрой и надежной системе управления зависимостями Swift.
SE-0379: Метаданные отражения Swift Opt-In
Ссылки: документ с предложением 📝 | Обзор 🧵
Используете ли вы API отражения в Swift в своих приложениях? Напоминаем: отражение — это процесс построения вашей логики на структуре вашего (или чужого) кода Swift. Например, для типа Person вы можете использовать тип Mirror и передать ему объект типа Person, чтобы получить информацию о свойствах и их именах, чтобы действовать соответствующим образом. Вы можете подумать, что это кажется полезным лишь в редких случаях, но я уверен, что вы уже использовали API-интерфейсы отражения. Если вы выполняли какую-либо отладку, скорее всего, вы использовали один из методов print, debugPrint или dump и уже передавали им объект. Попробуйте угадать, но причина, по которой они дают вам полезную информацию, заключается в том, что они используют Reflection под капотом!
Но независимо от того, планируете ли вы когда-нибудь в будущем явно использовать API-интерфейсы отражения или нет, это предложение принесет пользу всем: поскольку оно вводит детальный контроль над тем, когда отражение для типа необходимо, а когда нет, и обеспечивает обратную связь во время компиляции. По сути, до сих пор весь код должен был быть скомпилирован таким образом, чтобы сделать возможным отражение, добавляя метаданные в двоичный файл вашего приложения, такие как имена свойств firstName и lastName для типа, такого как Person — на всякий случай, если какая-то библиотека или SDK, которые вы использовали, полагались на отражение, как это делает SwiftUI для отслеживания изменений в вашей модели. Конечно, это означает, что гораздо проще реконструировать наш скомпилированный код обратно в его исходную кодовую форму с такими видами метаданных, чем если бы имя свойства было неясным. Кроме того, в настоящее время можно полностью отключить генерацию метаданных отражения без каких-либо предупреждений компилятора, что может привести к неожиданному поведению.
Это предложение направлено на решение этой проблемы путем введения нового протокола Reflectable для маркировки типов, которые должны явно поддерживать метаданные отражения, поэтому только для этих типов предоставляются полные метаданные. Предоставляется способ миграции, чтобы существующий код не сломался сразу. Вместо этого пользователи Swift (вероятно) сначала получат предупреждение, чтобы они могли перенести свои типы в Reflectable. Только после выхода Swift 6 новое поведение будет активировано по умолчанию (используйте флаг -enable-full-reflection-metadata, чтобы включить его до выхода этого обновления). Те, кто хочет явно использовать отражение в своем коде, могут указать, что их функции работают только с типами, которые соответствуют Reflectable и таким образом они могут быть уверены, что они могут работать с предоставленными данными. А для тех, кто просто хочет использовать API-интерфейсы, которые используют отражение «под капотом», они получат ошибку во время компиляции, если будут передавать данные, которые не соответствуют Reflectable, что делает код отражения Swift более безопасным, надежным и одновременно более трудным для реверс-инжиниринга.
SE-0380: выражения `if` и `switch`
Ссылки: документ с предложением 📝 | Обзор 🧵
Рассмотрим этот пример кода, показывающий часть логики для приложения для игры в шахматы. Отдельно прочитайте добавленные мной комментарии, показывающие различные шаблоны реализации:
Конечно, этот код можно реорганизовать несколькими способами, но давайте остановимся на этом примере кода в образовательных целях. Бывают случаи, когда некоторым разработчикам (включая меня) действительно нужна такая встроенная структура, особенно если мы хотим возвращать разные, но простые и понятные значения для разных случаев в коде. Что ж, у меня для вас отличные новости, потому что это заявка делает именно это и во многих отношениях упрощает приведенный выше код:
Во-первых, нам больше не нужно указывать ключевое слово return в операторах if или switch, если (и только если) все ветки имеют ровно один оператор и когда тип этого оператора одинаков для всех (независимо!). Во-вторых, нам больше не нужно писать самовыполняющееся замыкание в этих случаях, мы можем напрямую присваивать значения переменным из оператора if или switch. Последний аспект на самом деле является тем, что отличает простое утверждение от выражения: Выражение всегда вычисляется до значения, где оператор if или switch является только структурой для условного кода, оператор не (обязательно) вычисляется до значения. Но if и switch теперь будут использоваться в качестве выражений при возврате из функций / свойств / замыканий или при назначении переменным.
С этим предложением приведенный выше код можно записать как:
Я подчеркнул различия в комментариях. Разве так ненамного чище? Лично я время от времени использую самоисполняющиеся замыкания, так что теперь, когда я могу избавиться от них вместе с ключевым словом return, действительно делает код более естественным для меня. Сегодня я предпочитаю помещать каждый возврат в switch-case в отдельную строку плюс пустую строку перед следующим регистром для лучшей читаемости, в результате чего они становятся действительно раздутыми (см., пример здесь). Я обязательно рассмотрю возможность вернуться к виду в одной строке в будущем!
SE-0381: Удаление групп задач
Ссылки: документ с предложением 📝 | Обзор 🧵
Это улучшение структурированного параллелизма в Swift, в первую очередь направленное на улучшение управления памятью на сервере. Если вы новичок в новых механизмах параллелизма Swifts, таких как async/ await или with(Throwing)TaskGroup, вы можете прочитать разделы «Предлагаемое решение» двух наиболее актуальных замечаний, поскольку я не могу кратко обобщить их здесь, плюс они довольно хорошо написаны: SE-0296 Async/await и SE-0304 Структурированный параллелизм.
Короче говоря, это предложение вводит два новых варианта TaskGroup (в настоящее время у нас есть TaskGroup и ThrowingTaskGroup), которые не работают как последовательность и, следовательно, не соответствуют AsyncSequence (в отличие от TaskGroup/ ThrowingTaskGroup). Вместо этого они автоматически очищают все дочерние Task элементы, которые завершены, и потенциально могут привести их в соответствие с Sendable, что запланировано в будущих предложениях. Новые типы DiscardingTaskGroup и ThrowingDiscardingTaskGroup предоставляются в качестве параметра новой функции with(Throwing)DiscardingTaskGroup. Помимо уже упомянутых различий, они работают точно так же, как предыдущие типы групп задач (и связанная с ними глобальная функция with(Throwing)TaskGroup).
Автоматическая очистка дочерних задач делает эти новые типы подходящими для любой ситуации, когда события используются в течение более длительного периода времени при создании (потенциально длительных) задач. Идеальным вариантом использования для этого является сервер HTTP или RPC-сервер, который обрабатывает неопределенное количество запросов. Сегодня невозможно написать код параллелизма, экономящий память, для подобных сценариев.
Впечатляет то, как Swift на сервере постоянно развивается и двигается вперед в течение такого длительного времени, а сколько еще запланировано на будущее!
Недавние презентации/обсуждения
Некоторые темы в категории «Эволюция» с активностью в течении последних 2 месяцев я еще не освещал. Я подробно расскажу о них, как только (и если) они станут предложениями:
- Наблюдение
- Отражение
- Символьные литералы в одинарных кавычках
- Новый модификатор доступа: пакет
- Переменные Inout в циклах for-in
- Пользовательские атрибуты метаданных
- 'содержит(_:)` для диапазонов
- Целевые пакеты кросс-компиляции
- Неквалифицированный поиск в построителе результатов
- Разрешить "Property wrappers" для Let Declations
- Не копируйте `self` при вызове немутирующих методов.
Другие разработки, которые следует отметить
Я заметил, что в Swift Evolution, похоже, появился новый процесс, который я бы назвал «Разработка, управляемая видением». У нас всегда были манифесты в проекте с открытым исходным кодом Swift, такие как StringManifesto или недавно очень актуальные GenericsManifesto и OwnershipManifesto. Каждый из них утверждал, что является видением своей темы. Я также иногда видел, что первое предложение связанного набора предложений частично использовалось в качестве своего рода концептуального документа, такого как тип и обзор регулярных выражений SE-0350.
Но по мере роста кодовой базы Swift развивается и процесс Swift Evolution, и поэтому мы получили формализацию такого рода концептуальных документов. По сути, к proposals каталогу в репозитории Swift Evolution GitHub добавлен каталог visions. И все документы vision будут проходить упрощенный (внутренний) процесс проверки перед тем, как быть официально «принятыми», и, следовательно, будут еще более надежными, чем раньше, когда процесс создания этих документов не был ясен.
Первое уже принятое vision — « Использование Swift из C++ » (см. обсуждение ). Опубликовано еще два перспективных концептуальных документа, один о Variadic Generics (обсуждается здесь ) и один о макросах (обсуждается здесь ). На такого рода формализацию приятно смотреть, поскольку она еще больше упрощает процесс эволюции.
Кроме того, от Apple поступило несколько интересных новостей о Swift: во-первых, в блоге Swift были объявлены основные направления проектов Swift на 2023 год, которые стоит прочитать (связанное обсуждение на форумах Swift). Я просто хочу выделить две вещи, которые можно было бы легко упустить из виду: Рабочая группа по документации включит рекомендации по написанию отличной документации в новую книгу « Язык программирования Swift » с открытым исходным кодом, которую я действительно очень ценю. И Language Workgroup опубликует подробную документацию, включая рекомендации для авторов предложений и рецензентов, что на мой взгляд поможет привлечь больше разработчиков к написанию или рассмотрению предложений Evolution в будущем. Но это далеко не все, что есть в статье, в ней гораздо больше!
Во- вторых, Apple объявила , что Foundation теперь с открытым исходным кодом! Ладно, это не код Foundation, который мы используем сегодня (он, вероятно, содержит много старого кода Obj-C и даже обернутого кода C), но они делают максимум из возможного, то есть переписывают Foundation в Swift с открытым исходным кодом, который заменит Foundation на платформах Apple в будущем. Наконец, среда Swift on Server наконец-то получит доступ ко всему коду Foundation.
Они воспользуются этой возможностью, чтобы правильно сгруппировать вещи в более мелкие пакеты и FoundationEssentials станет еще более компактной версией сегодняшней Foundation. Таким образом, вы можете пропустить нелокализованные проекты FoundationInternationalization или такие вещи, как поддержка XML или поддержка сети, там, где они вам не нужны. Кроме того, благодаря новому процессу внесения правок вы не только сможете копаться в коде, если столкнетесь с ошибками, и исправить их самостоятельно, но также сможете вносить в Foundation совершенно новые API.
2023 год обещает быть захватывающим годом для разработчиков Swift. Я в восторге!