Swift 5.6版本的新功能指南

346 阅读6分钟

Swift 5.6 现已正式发布!

感谢 Swift 社区中的每个人,感谢你们的讨论、建议、错误报告、拉动请求等等。

Swift 5.6包括对类型系统的一些增强,改进了与指针的互动,并增加了使用包管理器运行新插件命令的能力。

要想快速了解Swift 5.6的一些新内容,请看Paul Hudson整理的这个操场

如果你是Swift的新手,《Swift编程语言》是Swift编程语言的权威指南,已经为5.6版本进行了更新。Swift社区还维护了一些翻译。 它也可以在苹果图书商店免费获得。

语言和标准库

新功能和改进

Swift 5.6通过Swift进化过程中的一些提议增强了语言,包括:

  • SE-0290- 无法使用的条件
  • SE-0315- 类型占位符(以前的 "占位符类型")。
  • SE-0320- 允许将非String /Int 键入的Dictionary 编码为一个KeyedContainer
  • SE-0322- 临时未初始化的缓冲区
  • SE-0324- 放宽对C函数的指针参数的诊断方法
  • SE-0331- 从不安全的指针类型中删除Sendable的一致性
  • SE-0335- 引入存在式any
  • SE-0337- 渐进式迁移到并发检查

让我们仔细看一下下面的一些内容。

对类型系统的增强

类型占位符(SE-0315)

Swift 允许你使用类型推理从你的代码中省略冗长、偶然的细节。然而,在需要时写出明确的类型会让人觉得过分,因为你必须指定一个完整的类型,即使你的代码只需要类型的一个特定部分来提供清晰度:

enum Either<Left, Right> {
  case left(Left)
  case right(Right)
}

let either: Either<ClosedRange<Int>, Range<Int>> = .left(0...10)

有了类型占位符,你现在可以在你的代码中写部分类型注释,只提供必要的细节。类型占位符是用_写的,它指示编译器推断出缺少的类型:

enum Either<Left, Right> {
  case left(Left)
  case right(Right)
}

// Inferred as 'Either<ClosedRange<Int>, Range<Int>>'
let either: Either<_, Range<Int>> = .left(0...10)

存在性any (SE-0335)

Swift中的存在性类型用于存储符合特定协议的任何类型的值。如今,存在性类型使用普通的协议名称或协议组合来拼写:

protocol DataSourceObserver { ... }

struct DataSource {
  var observers: [DataSourceObserver] { ... }
}

一个存在性类型会抹去它的底层类型信息,这在你需要动态改变底层类型时很有用,但它禁止存在性类型具有其他有用的能力,如符合协议。现有的语法令人困惑,因为存在性类型看起来就像一个通用的一致性要求,它没有这些基本限制。

在 Swift 5.6 中,存在性类型可以用 any 关键字明确标记:

protocol DataSourceObserver { ... }

struct DataSource {
  var observers: [any DataSourceObserver] { ... }
}

改进与指针的互动

Swift 5.6 在处理不安全指针时引入了三项重大改进。

临时未初始化的缓冲区(SE-0322)

这引入了一种创建临时未初始化内存空间的新方法,这在与需要提供内存以存储计算结果的 C API 互动时特别有用。

放宽对C函数的指针参数的诊断(SE-0324)

这一变化允许将不安全指针的可变变体(例如:UnsafeMutablePointer )传递给采用不可变版本的API(例如:UnsafePointer ),而无需明确的转换。

从不安全指针类型中移除Sendable一致性(SE-0331)

早期采用Sendable的反馈显示,指针一致性有意想不到的负面影响,特别是对于隐式一致性,因为这些类型的行为像引用。

改进的并发安全模型

Swift 5.6 还包括对并发安全模型的若干改进。

增量迁移到并发性检查(SE-0337)

在Swift 5.6中,关于Sendable 的诊断默认是被抑制的,但可以通过明确定义符合Sendable 或使用-warn-concurrency 编译器标志来启用,从而实现向并发性检查的增量迁移路径。

生态系统

Swift 包管理器

Swift 包管理器在 Swift 5.6 中获得了可扩展性功能,同时还获得了一些重要的安全、性能和可靠性更新。

可扩展的构建工具(SE-0303)

引入了在 SwiftPM 中定义构建工具插件的能力,允许在构建期间自动调用自定义工具。构建工具插件侧重于在软件包构建期间的代码生成,例如从 .proto 文件或其他输入生成 Swift 源文件,以便让构建工具纳入构建图并以安全方式自动运行。

命令插件(SE-0332)

扩展了 SE-0303 首次引入的 SwiftPM 插件支持,允许定义自定义命令插件 - 用户可以直接从 SwiftPM CLI 或支持 Swift 包的 IDE 中调用插件,以便对其包执行自定义操作。命令插件指定了命令的语义意图--这可能是预定义的意图之一,如 "文档生成 "或 "源代码格式化",也可能是一个带有专门动词的自定义意图,可以传递给 swift 包命令。

其他更新包括:

  • SE-0305- 包管理器二进制目标的改进
  • 语义上的版本依赖现在可以针对只包含主要和次要版本标识符的Git标签名来解决。一个形式为X.Y的标签将被视为X.Y.0。这提高了与现有存储库的兼容性。
  • 为了提高软件包的安全性,SwiftPM 执行了首次使用信任(TOFU)验证。现在,当软件包第一次从 Git 仓库下载时,该软件包的指纹就会被记录下来。随后的下载必须有与之前记录的值相匹配的指纹,否则会导致构建警告或失败,具体取决于设置。
  • 对依赖性解析基础设施进行了多项改进,从而提高了依赖性解析的性能和可靠性

Swift-DocC 更新

Swift-DocC 现在可作为 SwiftPM 插件使用新的插件命令支持。请参阅文档,了解如何开始使用

此外,您现在可以使用 Swift-DocC 将静态内容发布到 GitHub 页面

其他增强功能包括:

  • docc 命令行工具现在是macOS和Linux平台的开源、发布Swift工具链的一部分。
  • Swift-DocC现在可以构建与静态托管环境(如GitHub Pages)兼容的文档。
  • Swift-DocC现在可以为命令行工具和应用程序等可执行目标制作文档。

请务必查看Joseph Heck的精彩博文,其中包括更多细节。

下载

官方二进制文件可从Swift.org下载,用于Xcode、Windows和Linux。Swift 5.6 也包含在Xcode 13.3 中。

我们还提供了用于 Amazon Linux 2 和 CentOS 7 的 RPM,仅供实验使用。请提供您的反馈

使用下面的说明进行 RPM 安装。

亚马逊Linux 2

$ curl https://download.swift.org/experimental-use-only/repo/amazonlinux/releases/2/swiftlang.repo > /etc/yum.repos.d/swiftlang.repo
$ amazon-linux-extras install epel
$ yum install swiftlang

CentOS 7

$ curl https://download.swift.org/experimental-use-only/repo/centos/releases/7/swiftlang.repo > /etc/yum.repos.d/swiftlang.repo
$ yum install epel-release
$ yum install swiftlang