Мы рады объявить о выходе Swift 6. Это новый крупный выпуск, который расширяет возможности Swift на большее количество платформ и доменов.
Многие знают Swift как язык для разработки приложений, ведь в App Store уже миллион приложений. Но Swift подходит не только для приложений. Безопасность, скорость и доступность Swift делают его отличным выбором для многих других областей применения, включая библиотеки, интернет-сервисы, а также наиболее критичный к производительности и безопасности код.
Swift 6 стал еще более масштабным благодаря новым возможностям низкоуровневого программирования, встроенному подмножеству языка Swift, расширенной поддержке Linux и Windows, новым кроссплатформенным API, включая новую библиотеку Swift Testing, и многим другим.
Читайте далее, чтобы узнать об изменениях в языке, стандартных библиотеках, отладке, поддержке платформ и дальнейших шагах для начала работы со Swift 6.
Язык и стандартная библиотека
Concurrency
Swift уже давно обеспечивает безопасность памяти, гарантируя, что переменные инициализируются до их использования, доступ к памяти не осуществляется после ее деаллокации, а индексы массивов проверяются на наличие ошибок выхода за границы. В Swift 6 появился новый режим языка, который расширяет гарантии безопасности Swift для предотвращения гонок данных в параллельном коде, диагностируя потенциальные гонки данных в вашем коде как ошибки компилятора.
Ранее в Swift 5.10 проверки безопасности гонок данных были доступны в виде предупреждений с помощью флага компилятора -strict-concurrency=complete. Благодаря улучшенному выводу Sendable и новому анализу компилятора при передаче изменяемого состояния от одного агента к другому, предупреждения Swift 6 о безопасности гонок данных имеют меньше ложных срабатываний. Более подробную информацию о языковом режиме Swift 6 и о том, как перейти на него, можно найти на сайте Swift.org/migration.
Swift 6 знаменует собой начало пути к тому, чтобы сделать безопасность data-race значительно проще. Удобство использования data-race safety остается областью активной разработки, и ваши отзывы помогут сформировать будущие улучшения.
Swift 6 также поставляется с новой библиотекой Synchronization для низкоуровневых API параллелизма, включая атомарные операции и новый API мьютекса.
Типизированные броски
Swift 6 позволяет функциям указывать тип ошибки, которую они выбрасывают, как часть своей сигнатуры. Эта возможность полезна в общем коде, который пересылает ошибки, брошенные в клиентском коде, или в средах с ограниченными ресурсами, которые не могут выделять память, например, во встроенном коде Swift.
Например:
func parseRecord(from string: String) throws(ParseError) -> Record {
// ...
}
Вызов parseRecord(from:) либо вернет экземпляр Record, либо выбросит ошибку типа ParseError. Блок do..catch определит ParseError как тип переменной ошибки:
do {
let record = try parseRecord(from: myString)
} catch {
// 'error' has type 'ParseError'
}
Типизированный throws обобщает метательные и неметательные функции. Функция, указанная как throws (без конкретного типа ошибки), эквивалентна функции, указанной как throws(any Error), в то время как небросающая функция эквивалентна функции, указанной как throws(Never). Вызовы функций с типом throws(Never) являются неброскими и не требуют обработки ошибок на месте вызова.
Типизированные броски также могут использоваться в общих функциях для распространения типов ошибок от параметров, что является более точным способом, чем повторные броски. Например, метод Sequence.map может передавать тип ошибки thrown из параметра закрытия, указывая, что он выбрасывает только ошибки того же типа, что и закрытие:
extension Sequence {
func map<T, E>(_ body: (Element) throws(E) -> T) throws(E) -> [T] {
// ...
}
}
Когда дается закрытие, которое выбрасывает ParseError, map будет выбрасывать ParseError. Если дано закрытие, не вызывающее отбрасывания, то E подразумевается как Never и map не будет отбрасываться.
Владение
В Swift 5.9 появились некопируемые типы с синтаксисом ~Copyable для моделирования ресурсов с уникальным правом собственности и написания кода с учетом требований производительности за счет устранения накладных расходов, связанных с копированием во время выполнения. Swift 6 теперь поддерживает эти типы с помощью системы generics, что позволяет писать общий код, работающий как с копируемыми, так и с некопируемыми типами.
Например:
protocol Drinkable: ~Copyable {
consuming func use()
}
struct Coffee: Drinkable, ~Copyable { /* ... */ }
struct Water: Drinkable { /* ... */ }
func drink(item: consuming some Drinkable & ~Copyable) {
item.use()
}
drink(item: Coffee())
drink(item: Water())
Протокол Drinkable не требует, чтобы его соответствующие типы были копируемыми. Это означает, что в общую функцию drink можно передавать как некопируемый тип Coffee, так и копируемый тип Water.
Операторы switch теперь можно писать так, чтобы избежать копирования в операциях сопоставления шаблонов перечисления. Это означает, что операторы switch могут использоваться с некопируемыми полезными нагрузками, а также могут обеспечить преимущества в производительности для копируемых полезных нагрузок, особенно тех, которые основаны на контейнерах копирования при записи, таких как Array и Dictionary.
Некопируемые типы уже используются во всех стандартных библиотеках. Например, новый тип Atomic в библиотеке Synchronization основан на ~Copyable, Optional и Result теперь могут обертывать некопируемые типы, а небезопасные типы буферных указателей теперь могут указывать на некопируемые элементы. Взаимодействие с C++ также использует некопируемые типы, чтобы передать в Swift типы C++ move-only.
Взаимодействие с C++
В Swift 5.9 была представлена двунаправленная совместимость с C++, что позволило без проблем внедрить Swift в большее количество существующих проектов. В Swift 6 поддержка совместимости расширена до типов C++ move-only, виртуальных методов, аргументов по умолчанию и большего количества стандартных библиотечных типов, включая std::map и std::optional.
К типам C++, не имеющим конструктора копирования, теперь можно обращаться из Swift 6 как к некопируемым типам с помощью ~Copyable. А для тех случаев, когда для повышения производительности полезно раскрыть тип C++ с конструктором копирования как ~Copyable в Swift, к типу C++ можно применить новую аннотацию SWIFT_NONCOPYABLE.
Swift теперь также поддерживает вызовы виртуальных методов C++ на типы, аннотированные как SWIFT_SHARED_REFERENCE или SWIFT_IMMORTAL_REFERENCE.
При вызове функций или методов C++, которые имеют значения аргументов по умолчанию для некоторых параметров, Swift теперь учитывает эти значения по умолчанию, а не требует явной передачи аргумента.
Встраиваемый Swift
Swift 6 включает предварительную версию Embedded Swift - подмножества языка и режима компиляции, подходящих для разработки встраиваемого ПО, например для программирования микроконтроллеров. Инструментарий поддерживает пустые платформы ARM и RISC-V.
Embedded Swift создает небольшие и автономные двоичные файлы, полагаясь на общую специализацию. Поскольку он не зависит от времени выполнения или метаданных типов, Embedded Swift подходит для платформ с ограниченным объемом памяти, а также для использования в низкоуровневых средах с ограниченными зависимостями от времени выполнения.
Embedded Swift остается экспериментальной функцией, которая продолжает развиваться до появления стабильной поддержки в будущем выпуске Swift.
128-битные целые числа
Swift 6 расширяет набор низкоуровневых целочисленных примитивов, добавляя подписанные и беззнаковые 128-битные целые типы. Они доступны на всех платформах Swift и предоставляют тот же API, что и другие типы целых чисел фиксированной ширины в стандартной библиотеке.
Улучшения производительности
В Swift 6 появился ряд улучшений производительности, включая count(where:) для упрощения подсчета количества элементов в последовательности, удовлетворяющих предикату, пакетную итерацию для написания естественных for-циклов по элементам в пакете параметров значения, контроль доступа для импорта для предотвращения утечки деталей реализации в ваши публичные API, макросы @attached(body) для синтеза и дополнения реализаций функций, макросы выражений в качестве аргументов по умолчанию и многое другое.
Полный список предложений по языку, которые были приняты в процессе Swift Evolution и реализованы в Swift 6, можно найти на панели Swift Evolution.
Отладка
Пользовательские сводки LLDB с помощью @DebugDescription
Swift 6 предоставляет новый отладочный макрос, позволяющий легко настроить отображение объекта в LLDB при использовании команды p, а также в представлении переменных в Xcode и VSCode, используя схему форматирования, которая не запускает произвольный код.
Типы, соответствующие CustomDebugStringConvertible, предоставляют свойство debugDescription, которое возвращает строку, описывающую объект. В LLDB команда po вызывает это вычисляемое свойство объекта. В отличие от этого, команда p использует форматеры сводных типов LLDB для прямого форматирования объекта с использованием сохраненных значений свойств.
@DebugDescription - это новый макрос в стандартной библиотеке, который позволяет задавать резюме типов LLDB для ваших собственных типов прямо в коде. Макрос обрабатывает свойство debugDescription, переводя простые строковые интерполяции, связанные с хранимыми свойствами, в сводки типов LLDB. Это позволяет LLDB использовать ваше пользовательское форматирование даже при использовании p, а также в окнах отображения переменных в Xcode или VSCode. Макрос может использовать существующее соответствие CustomDebugStringConvertible, или вы можете предоставить отдельную строковую интерполяцию только для использования в команде p LLDB. Предоставление отдельной строки описания LLDB полезно, если ваша реализация CustomDebugStringConvertible не удовлетворяет требованиям макроса @DebugDescription или если вы знакомы с синтаксисом строки описания LLDB и хотите использовать ее напрямую.
Например, следующий код настраивает то, как po в LLDB отображает тип организации, в соответствии с CustomDebugStringConvertible, а макрос @DebugDescription открывает это пользовательское форматирование для команды p и представления переменных:
@DebugDescription
struct Organization: CustomDebugStringConvertible {
var id: String
var name: String
var manager: Person
// ... and more
var debugDescription: String {
"#\(id) \(name) [\(manager.name)]"
}
}
(lldb) p myOrg
(Organization) myOrg = "`#100 Worldwide Travel [Jonathan Swift]`"
Улучшение производительности при запуске с явными модулями
Swift 6 значительно улучшает производительность запуска в отладчике при использовании явных сборок модулей. При отладке локально собранного кода LLDB теперь может импортировать явно собранные модули Swift и Clang непосредственно из артефактов сборки проекта. Это позволяет избежать необходимости перекомпиляции неявных зависимостей модулей Clang из исходного кода, что может занять много времени и очень чувствительно к проблемам с путями поиска заголовков. Если первая команда p или po в LLDB занимает много времени из-за компиляции модуля Clang, или если ваша отладка часто блокируется из-за проблем с импортом заголовков Clang, подумайте о внедрении явных модулей в вашем проекте!
Библиотеки
Foundation
Swift 6 унифицирует реализацию Foundation на всех платформах. Современная переносимая реализация Swift обеспечивает согласованность на всех платформах, она более надежна и имеет открытый исходный код. macOS и iOS начали использовать Swift-реализацию Foundation вместе со Swift 5.9, а Swift 6 привносит эти улучшения в Linux и Windows.
Основные типы, такие как JSONDecoder, URL, Calendar, FileManager, ProcessInfo и другие, были полностью переработаны в Swift. Эти типы имеют общую реализацию с macOS 15 и iOS 18, обеспечивая новый уровень кроссплатформенной согласованности, надежности и производительности. Недавно выпущенные API, такие как FormatStyle, ParseStrategy, Predicate и JSON5, из прошлых выпусков macOS и iOS теперь доступны на всех платформах Swift. Новые API Foundation, такие как Expression, улучшения перечисления календаря, правила повторения календаря, улучшения стиля форматирования и многое другое, доступны одновременно на macOS, iOS, Linux и Windows - и они были созданы при участии сообщества.
Если ваше приложение для Linux или Windows импортирует библиотеку Foundation из набора инструментов Swift сегодня, вы получите все эти улучшения бесплатно. А если ваше приложение особенно чувствительно к размеру двоичных файлов, вы можете импортировать библиотеку FoundationEssentials, которая предоставляет более целенаправленное подмножество функций Foundation, исключая данные об интернационализации и локализации.
Тестирование Swift
Swift 6 представляет Swift Testing, новую библиотеку тестирования, разработанную с нуля для Swift. Она включает в себя выразительные API, позволяющие легко писать и организовывать тесты. Она предоставляет подробную информацию о неудачных тестах с помощью макросов типа #expect. И она масштабируется на большие кодовые базы благодаря таким функциям, как параметризация, позволяющая легко повторить тест с разными аргументами.
Например:
@Test("Continents mentioned in videos", arguments: [
"A Beach",
"By the Lake",
"Camping in the Woods"
])
func mentionedContinents(videoName: String) async throws {
let videoLibrary = try await VideoLibrary()
let video = try #require(await videoLibrary.video(named: videoName))
#expect(video.mentionedContinents.count <= 3)
}
Swift Testing использует все преимущества макросов. Вложенные макросы @Test и @Suite объявляют тестовые функции и типы наборов соответственно, а также принимают аргументы (известные как трейты) для настройки различных моделей поведения. Макросы выражений #expect и #require проверяют ожидаемое поведение, а также захватывают богатое представление выражений и их подзначений для создания подробных сообщений о сбоях.
Поскольку Swift Testing включен непосредственно в цепочки инструментов Swift 6, вы можете импортировать Testing без необходимости объявлять зависимость от пакета. Это означает, что вашим тестам не нужно собирать Swift Testing или его зависимости (включая swift-syntax), а его макрореализация поставляется уже собранной. Менеджер пакетов в Swift 6 автоматически собирает и запускает тесты Swift Testing в дополнение к XCTests (если они присутствуют), а также показывает результаты работы обеих библиотек в журнале. Swift Testing поддерживает все платформы, которые официально поддерживает Swift, включая все платформы Apple, Linux и Windows.
Чтобы узнать больше об этом новом проекте с открытым исходным кодом, посетите репозиторий swift-testing на GitHub, а также примите участие в его текущем развитии на форумах.
Поддержка платформ
Swift предназначен для поддержки разработки и выполнения на всех основных операционных системах, а согласованность и расширение платформ лежат в основе способности Swift охватывать новые области программирования. В Swift 6 реализованы значительные улучшения для Linux и Windows, включая поддержку большего числа дистрибутивов Linux и архитектур Windows. Инструментальные цепочки для всех следующих платформ доступны для загрузки с сайта Swift.org/install.
Полностью статический SDK для Linux
Swift 6 поддерживает создание полностью статически связанных исполняемых файлов для Linux; они не имеют внешних зависимостей, поэтому идеально подходят для ситуаций, когда нужно скопировать программу непосредственно на систему или в контейнер и запустить ее без установки дополнительного программного обеспечения. SDK также можно использовать для кросс-компиляции в Linux с других платформ. Узнайте, как начать работу со статическим SDK для Linux, на сайте Swift.org.
Новые дистрибутивы Linux
В Swift 6 добавлена официальная поддержка и тестирование Debian и Fedora, а также Ubuntu 24.04.
Производительность сборки Windows
Теперь доступны готовые цепочки инструментов для архитектуры arm64, что повышает производительность компилятора для Windows на хостах ARM. В Swift 6 менеджер пакетов Swift также по умолчанию распараллеливает сборки на нескольких ядрах в Windows. На 10-ядерной машине это может повысить производительность сборки в 10 раз!
Следующие шаги
Скачать Swift 6
Вы можете опробовать эти захватывающие новые разработки в Swift 6 уже сегодня! Установите официальные цепочки инструментов Swift 6 для macOS, Linux и Windows на сайте Swift.org/install.
Начните работать со Swift
Книга «Язык программирования Swift» была обновлена с учетом новейшего синтаксиса и возможностей Swift 6. Она служит официальным руководством по Swift и отличной отправной точкой для изучения языка.
На сайте Swift.org/getting-started можно найти учебные пособия по различным областям применения, включая создание кроссплатформенной библиотеки, веб-сервиса с помощью Vapor и встраиваемого приложения для микроконтроллера. Там же есть статьи, позволяющие глубже погрузиться в некоторые из наиболее популярных функций Swift.
Изучите экосистему пакетов
Экосистема пакетов Swift постоянно пополняется новыми технологиями, которые помогут вам решать различные задачи в ваших проектах. Вы можете изучить основные пакеты на сайте Swift.org/packages, где представлены популярные категории пакетов и подборка новых и заметных пакетов, которые ежемесячно отбираются вручную в результате открытого процесса номинирования.
Примите участие
Ваш опыт работы со Swift 6 и ваши отзывы помогут сформировать будущую эволюцию языка, инструментов, экосистемы пакетов и сообщества. Вы можете принять участие в работе сообщества, делясь своими пакетами, улучшая документацию, образовательные материалы, сообщения об ошибках и запросы на улучшения, внося свой вклад в код и участвуя в обсуждениях на форуме. Узнайте больше на сайте Swift.org/contributing.
Swift 6 - это кульминация бесчисленных вкладов членов сообщества Swift, и он знаменует собой десятилетие совместного создания этого невероятного языка, экосистемы и сообщества. Спасибо всем, кто принимал участие в разработке и оставлял отзывы. Благодаря вашему вкладу Swift становится лучшим языком.