Swift 6 发布公告
我们很高兴地宣布 Swift 6 正式发布。这是一个重要的全新版本,将 Swift 扩展到更多平台和领域。
许多人知道 Swift 是一种用于应用程序开发的语言,App Store 上有数百万个应用程序。但 Swift 的用途远不止于应用程序。Swift 的安全性、速度和易用性使其成为许多其他用例的绝佳选择,包括库、互联网规模的服务以及性能至关重要且安全的代码。
Swift 6 通过新的底层编程特性、嵌入式 Swift 语言子集、扩展的 Linux 和 Windows 支持、新的跨平台 API(包括新的 Swift Testing 库)等进一步扩展了应用范围。
请继续阅读,深入了解语言、标准库、调试、平台支持的更改,以及开始使用 Swift 6 的后续步骤。
语言和标准库
并发
长期以来,Swift 一直提供内存安全,确保变量在使用前已初始化、内存不会在释放后被访问,并且数组索引会检查越界错误。Swift 6 现在包含一种新的、可选择启用的语言模式,扩展了 Swift 的安全保证,通过将代码中潜在的数据竞争诊断为编译器错误来防止并发代码中的数据竞争。
数据竞争安全检查以前在 Swift 5.10 中以警告的形式提供,通过 -strict-concurrency=complete
编译器标志。由于改进的 Sendable
推断和用于将可变状态从一个参与者转移到另一个参与者的新编译器分析,Swift 6 关于数据竞争安全的警告误报更少。您可以在 /migration 找到关于 Swift 6 语言模式以及如何迁移的更多信息。
Swift 6 标志着让数据竞争安全变得更加容易的旅程的开始。数据竞争安全的用户友好性仍然是一个活跃的开发领域,您的反馈将有助于塑造未来的改进。
Swift 6 还附带了一个新的 Synchronization 库,用于底层并发 API,包括原子操作和一个新的互斥锁 API。
类型化 throws
Swift 6 使函数能够在其签名中指定它们抛出的错误类型。此功能在通用代码中非常有用,通用代码可以转发客户端代码中抛出的错误,或者在无法分配内存的资源受限环境中非常有用,例如在嵌入式 Swift 代码中。
例如
func parseRecord(from string: String) throws(ParseError) -> Record {
// ...
}
调用 parseRecord(from:)
将返回一个 Record
实例或抛出一个 ParseError
类型的错误。do..catch
代码块将推断 ParseError
作为 error
变量的类型
do {
let record = try parseRecord(from: myString)
} catch {
// 'error' has type 'ParseError'
}
类型化 throws 概括了抛出和不抛出函数。指定为 throws
(没有特定错误类型)的函数等同于指定 throws(any Error)
的函数,而不抛出错误的函数等同于指定 throws(Never)
的函数。throws(Never)
函数的调用是非抛出的,并且在调用站点不需要错误处理。
类型化 throws 也可以在泛型函数中使用,以从参数传播错误类型,其方式比 rethrows
更精确。例如,Sequence.map
方法可以从其闭包参数传播抛出的错误类型,表明它只抛出与闭包相同类型的错误
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 现在在泛型系统中支持这些类型,从而可以编写适用于可复制和不可复制类型的泛型代码。
例如
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
协议没有要求其一致性类型是 Copyable
。这意味着不可复制类型 Coffee
和可复制类型 Water
都可以传递到泛型 drink
函数中。
现在可以编写 Switch 语句以避免在枚举模式匹配操作中进行复制。这意味着 Switch 语句可以与不可复制的有效负载一起使用,并且还可以为可复制的有效负载提供性能优势,尤其是那些基于写时复制容器(如 Array
和 Dictionary
)的有效负载。
不可复制类型已在整个标准库中使用。例如,Synchronization 库中的新 Atomic
类型基于 ~Copyable
,Optional
和 Result
现在可以包装不可复制类型,并且不安全缓冲区指针类型现在可以指向不可复制元素。C++ 互操作性也使用不可复制类型来将 C++ 仅移动类型暴露给 Swift。
C++ 互操作性
Swift 5.9 引入了与 C++ 的双向互操作性,以无缝地将 Swift 引入更多现有项目。Swift 6 扩展了对 C++ 仅移动类型、虚方法、默认参数以及更多标准库类型(包括 std::map
和 std::optional
)的互操作性支持。
现在可以从 Swift 6 中访问没有复制构造函数的 C++ 类型,作为带有 ~Copyable
的不可复制类型。并且在某些时候,为了获得更好的性能,将具有复制构造函数的 C++ 类型作为 Swift 中的 ~Copyable
公开很有用,新的 SWIFT_NONCOPYABLE
注解可以应用于 C++ 类型。
Swift 现在还支持在注解为 SWIFT_SHARED_REFERENCE
或 SWIFT_IMMORTAL_REFERENCE
的类型上调用 C++ 虚方法。
当调用 C++ 函数或方法时,如果它们的某些参数具有默认参数值,Swift 现在会尊重这些默认值,而不是要求您显式传递参数。
嵌入式 Swift
Swift 6 包含 嵌入式 Swift 的预览版,这是一种适用于嵌入式软件开发的语言子集和编译模式,例如微控制器编程。该工具链支持 ARM 和 RISC-V 裸机目标。
嵌入式 Swift 通过依赖泛型特化来生成小型且独立的二进制文件。由于它不依赖于运行时或类型元数据,因此嵌入式 Swift 适用于内存受限的平台以及运行时依赖性有限的底层环境中使用。
嵌入式 Swift 仍然是一个实验性功能,在未来的 Swift 版本中获得稳定支持之前,仍在进行开发。
128 位整数
Swift 6 通过添加有符号和无符号 128 位整数类型,完善了底层整数原语的集合。这些类型在所有 Swift 平台上都可用,并提供与标准库中其他固定宽度整数类型相同的 API。
生产力增强
Swift 6 引入了许多生产力增强功能,包括 count(where:)
以简化计算序列中满足谓词的元素数量、包迭代 用于编写对值参数包中的元素进行自然 for
循环、导入的访问控制以防止实现细节泄漏到您的公共 API 中、@attached(body)
宏用于合成和增强函数实现、表达式宏作为默认参数等等。
您可以在 Swift Evolution 仪表板上找到通过 Swift Evolution 流程接受并在 Swift 6 中实现的语言提案的完整列表。
调试
使用 @DebugDescription
的自定义 LLDB 摘要 @DebugDescription section" 的永久链接" href="#custom-lldb-summaries-with-debugdescription">
Swift 6 提供了一个新的调试宏,通过使用不运行任意代码的格式化方案,可以轻松自定义对象在使用 p
命令时以及在 Xcode 和 VSCode 的变量视图中的显示方式。
符合 CustomDebugStringConvertible
的类型提供了一个 debugDescription
属性,该属性返回描述对象的字符串。在 LLDB 中,po
命令在对象上调用此计算属性。相反,p
命令使用 LLDB 的类型摘要格式化程序,使用其存储的属性值直接格式化对象。
@DebugDescription
是标准库中的一个新宏,它允许您直接在代码中为自己的类型指定 LLDB 类型摘要。该宏处理 debugDescription
属性,将涉及存储属性的简单字符串插值转换为 LLDB 类型摘要。这允许 LLDB 即使在使用 p
时以及在 Xcode 或 VSCode 的变量显示窗口中也使用您的自定义格式。宏可以使用对 CustomDebugStringConvertible
的现有一致性,或者您可以仅提供一个单独的字符串插值以用于 LLDB 的 p
命令。如果您的 CustomDebugStringConvertible
实现不满足 @DebugDescription
宏的要求,或者您熟悉 LLDB Summary String 语法 并且想要直接使用它,则提供单独的 LLDB 描述字符串非常有用。
例如,以下代码自定义了 LLDB 中的 po
如何通过符合 CustomDebugStringConvertible
来显示 Organization
类型,并且 @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 模块依赖项的需求,这可能需要很长时间,并且对头文件搜索路径的问题非常敏感。如果 LLDB 中的第一个 p
或 po
命令由于 Clang 模块编译而花费很长时间,或者如果您的调试经常被 Clang 头文件导入问题阻止,请考虑在您的项目中采用显式模块!
库
Foundation
Swift 6 统一了所有平台上 Foundation 的实现。现代化的、可移植的 Swift 实现提供了跨平台的一致性,它更健壮,并且是开源的。macOS 和 iOS 在 Swift 5.9 中开始使用 Swift 实现的 Foundation,而 Swift 6 将这些改进带到了 Linux 和 Windows。
像 JSONDecoder
、URL
、Calendar
、FileManager
、ProcessInfo
等核心类型已在 Swift 中完全重新实现。这些类型与 macOS 15 和 iOS 18 共享其实现,提供了新的跨平台一致性、可靠性和性能水平。最近发布的 API,如 FormatStyle
、ParseStrategy
、Predicate
和 JSON5
,来自过去的 macOS 和 iOS 版本,现在在所有 Swift 平台上都可用。新的 Foundation API,如 Expression
、日历枚举改进、日历重复规则、格式样式增强等,在 macOS、iOS、Linux 和 Windows 上同时可用 - 并且它们是在社区参与下构建的。
如果您的 Linux 或 Windows 应用程序今天从 Swift 工具链导入 Foundation
库,您将免费获得所有这些改进。如果您的应用程序对二进制大小特别敏感,您现在可以导入 FoundationEssentials
库,该库提供了更有针对性的 Foundation 功能子集,省略了国际化和本地化数据。
Swift Testing
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 工具链中,因此您可以 import Testing
而无需声明包依赖项。这意味着您的测试不需要构建 Swift Testing 或其依赖项(包括 swift-syntax),并且其宏实现是预构建的。Swift 6 中的包管理器会自动构建和运行 Swift Testing 测试以及 XCTest(如果存在),并在日志输出中显示来自这两个库的结果。Swift Testing 支持 Swift 官方支持的所有平台,包括所有 Apple 平台、Linux 和 Windows。
要了解有关这个新的开源项目的更多信息,请访问 GitHub 上的 swift-testing 仓库,并参与其在 论坛 上的持续开发。
平台支持
Swift 旨在支持在所有主要操作系统上进行开发和执行,平台一致性和扩展性是 Swift 扩展到新的编程领域的基础。Swift 6 全面改进了 Linux 和 Windows,包括支持更多 Linux 发行版和 Windows 架构。以下所有平台的工具链均可从 /install 下载。
Linux 的完全静态 SDK
Swift 6 支持为 Linux 构建完全静态链接的可执行文件;这些文件没有外部依赖项,因此非常适合您希望将程序直接复制到系统或容器中并运行它而无需安装任何额外软件的情况。SDK 还可以用于从其他平台交叉编译到 Linux。了解如何开始使用 Linux 的静态 SDK,请访问 。
新的 Linux 发行版
Swift 6 增加了对 Debian 和 Fedora 以及 Ubuntu 24.04 的官方支持和测试。
Windows 构建性能
预构建的工具链现在可用于 arm64 架构,这为 ARM 主机上的 Windows 提供了改进的编译器性能。在 Swift 6 中,Swift 包管理器默认情况下还在 Windows 上跨多个核心并行构建。在一台 10 核机器上,这可以将构建性能提高多达 10 倍!
下一步
下载 Swift 6
您今天就可以试用 Swift 6 中这些令人兴奋的新进展!在 /install 上安装适用于 macOS、Linux 和 Windows 的官方 Swift 6 工具链。
开始使用 Swift
《Swift 编程语言》 书籍已更新,以反映最新的 Swift 6 语法和特性。它作为官方 Swift 指南,是学习该语言的绝佳起点。
为了帮助您快速开始您的 Swift 之旅,/getting-started 提供了各种用例的教程,包括构建跨平台库、使用 Vapor 的 Web 服务以及用于微控制器的嵌入式应用程序。还有一些文章深入探讨了 Swift 最受欢迎的一些功能。
探索包生态系统
Swift 包生态系统正在不断发展,新技术可以帮助您完成项目中的各种任务。您可以在 /packages 上探索包亮点,其中包含流行的包类别以及每月从公开提名过程中手工精选的新软件包和著名软件包。
参与其中
您使用 Swift 6 的体验和您的反馈可以帮助塑造语言、工具、包生态系统和社区的未来发展。您可以通过分享您的包、文档改进、教育内容、错误报告和增强请求、代码贡献以及参与论坛讨论来参与其中。在 /contributing 了解更多信息。
Swift 6 是来自整个 Swift 社区成员的无数贡献的结晶,它标志着共同构建这个令人难以置信的语言、生态系统和社区的十年。感谢所有参与开发并提供反馈的人。您的贡献使 Swift 成为更好的语言。