Swift 5.6 正式发布,新功能一览

3,477 阅读4分钟

Swift 5.6 现已正式发布!新版本包括了很多对类型系统的增强,改进了与指针的交互,并增加了使用包管理器运行新插件命令的能力。

语言和标准库

新功能和改进

Swift Evolution 提议在Swift 5.6 中得以实现,包括:

  • SE-0302 - Sendable@Sendable封闭
  • SE-0315 - 类型占位符(以前称为“占位符类型”)
  • SE-0320 - 允许将非String/Int键入Dictionary的编码KeyedContainer
  • SE-0322 - 临时未初始化的缓冲区
  • SE-0324 - 放宽 C 函数指针参数的诊断
  • SE-0331 - 从不安全的指针类型中删除可发送一致性
  • 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)

existential any( SE-0335 )

Swift 中的existential 类型用于存储符合特定协议的任何类型的值。今天,existential 类型支持使用简单的协议名称或协议组合拼写:

protocol DataSourceObserver { ... }

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

existential 类型会擦除其基础类型信息,这很适合需要动态更改基础类型的场景,不过它会禁止existential 类型使用其他有用的功能,例如符合协议。

在 Swift 5.6 中,existential 类型可以用 any 关键字显式标记:

protocol DataSourceObserver { ... }

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

改进与指针的交互

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

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

引入一种创建临时未初始化内存空间的新方法,适用场景:与需要提供用于存储计算结果内存的 C API 交互。

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

允许将不安全指针的可变体(例如UnsafeMutablePointer)传递给采用不可变体(例如UnsafePointer)的API,而无需显式转换。

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

早期采用 Sendable 的反馈表明,指针一致性具有意想不到的负面影响,尤其是对于隐式一致性,因为这些类型的行为类似于引用。

改进的并发安全模型

Swift 5.6 还包括对并发安全模型的一些改进:

  • Sendable@Sendable关闭 ( SE-0302 )
  • 增量迁移到并发检查 ( SE-0337 )

生态系统

Swift 包管理器

Swift 5.6 中Swift 包管理器在可扩展性、安全性、性能和可靠性都得到了更新。

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

引入在 SwiftPM 中定义构建工具插件的能力,允许在构建过程中自动调用自定义工具。构建工具插件专注于构建包期间的代码生成,例如从 .proto 文件或其他输入生成 Swift 源文件,允许将构建工具合并到构建图中并自动运行一种安全的方式。

命令插件 ( SE-0332 )

扩展 SE-0303 首次引入的 SwiftPM 插件支持,允许定义自定义命令插件,用户可以直接从 SwiftPM CLI 或支持 Swift 包的 IDE 调用插件。

其他更新包括:

  • SE-0305:包管理器二进制目标改进
  • 针对仅包含主要和次要版本标识符的 Git 标记名称来解析语义版本依赖关系。具有 XY 形式的标签将被视为 XY0,提高了与现有存储库的兼容性。
  • 为了提高包的安全性,SwiftPM 执行首次使用时的信任 (TOFU) 验证。当第一次从 Git 存储库下载包时,会记录包的指纹。后续下载的指纹必须与之前记录的值匹配,否则会根据设置导致构建警告或失败。
  • 针对依赖关系解析基础设施进行多项改进,从而提高依赖关系解析的性能和可靠性