Swift 5.9 发布

Swift 5.9 现已发布!🎉

这是一个重要的全新版本,为语言添加了富有表现力的宏系统,并引入了通过双向互操作性将 Swift 集成到 C++ 代码库中的支持

它还引入了参数包、改进的调试表达式求值器、增强的崩溃处理、Windows 平台改进等等。

请继续阅读,深入了解语言、标准库、工具、平台支持的更改,以及开始使用 Swift 5.9 的后续步骤。

感谢 Swift 社区中使此版本成为可能的所有人。非常感谢您在 Swift 论坛上的讨论、错误报告、pull request、教育内容和其他贡献!

语言和标准库

Swift 的基本目标是鼓励代码清晰简洁,同时保持安全高效。

此版本添加了三个长期以来期望的功能,进一步实现了该目标:用于更具表现力的库的新宏系统、使重载 API 使用起来更自然的参数包,以及新的所有权特性,以便在底层代码中提供更多性能控制。

帮助开发者减少重复的样板代码,并创建更具表现力的库,这些库可以作为 Swift 包分发。

使用宏简单自然。宏可以使用类似函数的独立 #macroName 语法展开

let _: Font = #fontLiteral(name: "SF Mono", size: 14, weight: .regular)

或使用 @MacroName 属性附加到声明

// Move storage from the stored properties into a dictionary,
// turning the stored properties into computed properties.
@DictionaryStorage
struct Point {
  var x: Int = 1
  var y: Int = 2
}

它们的工作方式与内置语言特性完全相同,但不会被误认为是普通代码。

您可以使用强大而灵活的方法编写宏:它们只是使用 SwiftSyntax 库生成要插入到源文件中的代码的 Swift 函数。

宏使您的库用户可以轻松采用强大的功能,这些功能可以适应他们使用的代码,例如 新的 Observation 模块,该模块允许 Swift 类在其属性更改时自动通知其他代码。

Swift 社区一直在努力创建基于宏的工具和框架。例如,请查看 swift-power-assertswift-spyableswift-macro-testingMetaCodable

Swift 5.9 在 macOS 和 Linux 上支持宏,Windows 支持即将推出。

参数包

参数包允许您编写可以处理任意数量类型的泛型类型和函数。

例如,如果没有参数包,如果您想编写一个名为 all 的函数来检查任意数量的 Optional 值是否为 nil,则需要为您要支持的每个参数长度编写单独的重载,从而创建任意上限

func all<W1>(_ optional: W1?) -> W1?
func all<W1, W2>(_ optional1: W1?, optional2: W2?) -> (W1, W2)?
func all<W1, W2, W3>(_ optional1: W1?, optional2: W2?, optional3: W3?) -> (W1, W2, W3)?

使用参数包,您可以将此 API 表示为单个函数,该函数没有上限,允许您传递任意数量的参数

func all<each Wrapped>(_ optional: repeat (each Wrapped)?) -> (repeat each Wrapped)?

调用使用参数包的 API 很直观,不需要额外的工作

if let (int, double, string, bool) = all(optionalInt, optionalDouble, optionalString, optionalBool) {
  print(int, double, string, bool)
}
else {
  print("got a nil")
}

所有权

所有权特性可以帮助开发者微调性能关键代码中的内存管理行为。

新的 consume 运算符告诉 Swift 反初始化变量并在不复制的情况下传输其内容。consumingborrowing 参数修饰符提供了提示,Swift 可以使用这些提示来消除传递参数时不必要的复制和引用计数操作。最后,不可复制的结构体和枚举允许您创建类型,这些类型像类一样,在赋值时不能有意义地复制,但像结构体或枚举一样,不需要引用计数,因为一次只有一个存储位置可以拥有该实例。

这些主要特性是进一步演化的基础,可以将更具表现力的能力和性能控制权交到您手中。我们对您可以使用 Swift 5.9 做的事情感到兴奋,并且我们正在努力实现具有更大套件的可变泛型和所有权特性的未来。

其他特性

Swift 5.9 还包括对语言进行小的、提高生活质量的更改,例如能够使用 ifswitch 作为表达式进行变量赋值和返回值

statusBar.text = if !hasConnection { "Disconnected" }
                 else if let error = lastError { error.localizedDescription }
                 else { "Ready" }

新的 package 访问级别允许同一包中的其他模块访问 API,但对包外部的代码隐藏它们。这非常适合将大型模块拆分为几个较小的模块,而不会将内部组件暴露给包的客户端。

使用 Swift 并发的开发者可能会喜欢更方便的 DiscardingTaskGroup 类型,用于不生成结果的任务组,以及高级 自定义 actor 执行器功能,用于控制 actor 运行的确切环境。

Swift 5.9 演化提案的完整列表可以在本文末尾找到。

开发者体验

崩溃处理

在 Linux 上,Swift 运行时现在将捕获程序崩溃和 Swift 运行时错误,并在程序的输出中显示回溯。回溯器是进程外的,包括对 async 函数的支持。

此功能在 macOS 上也可用,但默认情况下禁用。要启用它,请设置 SWIFT_BACKTRACE=enable=yes 并使用 com.apple.security.get-task-allow 授权签名您的程序。

调试

Swift 5.9 引入了 LLDB 和 Swift 编译器的新功能,旨在使 Swift 调试更快、更可靠。

ppo 命令现在打印局部变量和属性的速度与 frame variablev 命令一样快,方法是在求值简单表达式时绕过 Swift 编译器。

Swift 表达式现在可以引用泛型类型参数。这允许在泛型函数中设置条件断点,该断点仅在类型参数使用特定的具体类型实例化时触发。

Swift 编译器生成的调试信息现在更精确地限定了局部变量的范围,从而减少了在调试器中显示由未初始化内存支持的变量的可能性。

生态系统

C++ 互操作性

Swift 5.9 支持与 C++ 和 Objective-C++ 进行双向互操作,以实现某些类型的 API。

例如,如果您有一个像这样的 C++ 函数

// Clang module 'PromptResponder'
#pragma once
#include <vector>

std::vector<std::string> generatePromptResponse(std::string prompt);

您可以直接从 Swift 代码中调用它

import PromptResponder

let codeLines = generatePromptResponse("Write Swift code that prints hello world")
  .map(String.init)
  .filter { !$0.isEmpty }

for line in codeLines {
  print(line)
}

C++ 互操作性正在积极发展,某些方面可能会在未来的版本中发生变化,因为社区会收集混合 Swift 和 C++ 代码库中实际采用的反馈。

有关启用 C++ 互操作性和支持的语言子集的信息,请参阅文档

特别感谢 C++ 互操作性工作组 在支持此功能方面的专注和奉献。

Swift Package Manager

Swift Package Manager 在 Swift 5.9 中进行了许多改进

有关完整的更改列表,请参阅 Swift Package Manager 变更日志

Swift Syntax

swift-syntax 是解析 Swift 代码的重要工具,有助于支持新的宏系统。今年,swift-syntax 进行了许多改进

在过去一年中,swift-syntax 作为一个开源项目取得了巨大的成功。自 Swift 5.8 发布以来,超过 30 位不同的贡献者参与了该软件包的开发,占提交的 30% 以上。此外,社区工具 swift-ast-explorer.com 对于探索和理解 SwiftSyntax 树非常宝贵。感谢每一位贡献者!

服务器

Swift 5.9 的自定义 actor 执行器和其他功能正在进入服务器端 Swift 生态系统。

服务器工作组最近还发布了 2023 年度更新,详细介绍了在关键库中增加并发采用率的计划,以及其他工作。

Windows 平台

Swift 5.9 的 Windows 支持极大地提高了稳定性和开发者体验。

Windows 安装程序现在支持在 Visual Studio 安装之前和之后进行安装,并且在 Visual Studio 升级后不再需要修复。启用在 Windows 上并行安装多个工具链的初步工作也已开始。

Swift 工具链还添加了新的标志 (-windows-sdk-root, -windows-sdk-version, -visualc-tools-root, -visualc-tools-version) 以帮助控制它构建时所针对的 Windows SDK 和 Visual C++ 工具。

Windows SDK (WinSDK) 模块在覆盖范围上有所改进,从而可以访问更广泛的系统 API。Visual C++ (vcruntime) 模块经过了大幅度重构,以支持 C++ 互操作性。

结构化并发在 Windows 上现在明显更加稳定,消除了常见模式(例如迭代具有许多元素的 AsyncStream)的堆栈溢出和其他执行失败。

LSP 和 SwiftPM 中路径处理的改进使这两种工具在 Windows 上更加健壮。LLDB 也开始进行初步工作,以改进对 Windows 的支持,从而在 Windows 上的 LLDB 中启用基本的调试工作流程。虽然仍在进行中,但这将显著改善 Windows 上的开发者体验。

还进行了一些小的改进,以减小 Windows 上工具链的大小。

后续步骤

下载

可以从 下载官方二进制文件,适用于 macOS、Windows 和 Linux。Swift 5.9 编译器也包含在 Xcode 15 中。

网站

改进了一些关键页面,包括 更丰富的主页 和更清晰的 下载和安装说明

如果您是 Swift 新手或希望深入了解,请查看更新后的入门指南

语言指南

《Swift 编程语言》一书已针对 Swift 5.9 进行了更新,现在通过 DocC 发布。

这是官方 Swift 指南,是学习 Swift 的绝佳入门点。

Swift 社区还维护着许多译本

Swift Evolution 附录

以下语言、标准库和 Swift Package Manager 提案已通过 Swift Evolution 流程并在 Swift 5.9 中实现