Swift 5.4 发布!
Swift 5.4 现已正式发布!此版本包含各种语言和工具改进。
您可以尝试 Paul Hudson 整理的这个 playground 中的一些新功能。
上现在提供了 Swift 5.4 的更新版本《Swift 编程语言》。它也可以在 Apple Books 商店 中免费获取。
语言更新
Swift 5.4 包括以下新的语言特性
为了为新的并发模型做准备,编译器现在会针对不合格地使用 await 作为标识符发出警告和修复建议。这些标识符将在未来版本的 Swift 中被解释为关键字 await,这是 SE-0296 的一部分。
运行时性能和代码大小改进
在 Swift 5.4 中,由于更快的哈希表实现用于缓存之前的查找结果,因此运行时协议一致性检查速度显著加快。特别是,这加快了常见的运行时 as? 和 as! 转换操作。
此外,连续的数组修改现在避免了冗余的唯一性检查。
func foo(_ a: inout [Int]) {
// Must do copy-on-write (CoW) check here.
a[0] = 1
// The compiler no longer generates
// a redundant CoW check here.
a[1] = 2
}
最后,还有各种性能改进
String插值更积极地进行常量折叠- 更少的 retain/release 调用,特别是对于
inout函数参数和循环内部 - 标准库中的泛型元数据现在在 编译时进行预先专门化,从而减少脏内存使用并提高性能
Swift 包管理器更新
Swift 5.4 中的 Swift 包管理器有几个重要的更新
- 指定 5.4 工具版本的 Swift 包现在可以显式声明目标为可执行文件,这允许在包代码中使用
@main关键字 (SE-0294) - Swift 包管理器现在支持 Windows!
- Swift 包管理器在每个用户的基础上缓存包依赖项,这减少了网络流量,并提高了后续使用相同包时依赖项解析的性能
- 自动测试发现现在是所有平台上的默认设置,无需
LinuxMain.swift(已弃用) - 依赖项解析基础结构的多次改进,包括清单加载和缓存,从而提高了依赖项解析的性能
- 改进的诊断基础结构和错误消息,为依赖项解析问题及其他问题提供更可操作的错误消息
Windows 平台支持
Windows 上对 Swift 的支持在几个重要方面取得了进展
- Swift 包管理器现在可以在 Windows 上运行
WinSDK模块已得到扩展,涵盖了 Windows 开发者 SDK 的更大部分。这使得更多 API 可以轻松地用于 Windows 应用程序,而无需手动构建库来桥接 C 接口到 Swift- 安装程序的改进应通过减少 Windows 上默认所需的标志,使工具链与外部工具一起使用更加容易
开发者体验改进
构建性能
- Swift 编译器在跟踪文件之间的依赖关系方面做得更好,从而在增量构建期间,对于许多类型的更改,显著减少了编译的文件数量
- Swift 编译器现在单独跟踪结构体、枚举、类和协议的成员变量和函数的依赖关系。这种更精细的粒度加速并缩小了在更改这些实体后重建的规模
- 增量构建在更多情况下产生确定性的产品
代码补全
在大型函数体中,代码补全的性能现在更快得多。在 swift-package-manager 仓库中的一个示例中,对于该文件中重复调用,Swift 5.4 中 self. 的代码补全时间现在比 Swift 5.3 快 4 倍(20 毫秒 → 5 毫秒)。
代码补全在包含错误的表达式以及在没有额外上下文的情况下不明确的表达式中也更加可靠。例如,给定
func test(a: Int, b: String) -> Int { ... }
func test(a: Int, b: Int) -> String { ... }
func test(a: (Int, Int) -> Int) -> Int { ... }
对于上面的代码,代码补全现在具有以下行为
- 在
test().prefix(3).之后调用代码补全会建议String的成员 - 在
test(a: 2).之后调用代码补全会建议Int和String的成员 - 在以下代码块中,在
$0.之后调用代码补全会建议Int的成员:test { $0. }
类型检查器
Swift 5.4 改进了对“链接”表达式(例如 a + b + (2 * c))的类型检查性能。例如,考虑
struct S { var s: String? }
func test(_ a: [S]) {
_ = a.reduce("") {
($0 + "," + ($1.s ?? "")) + ($1.s ?? "") + ($1.s ?? "")
}
}
对于此代码,类型检查器在 100 毫秒内完成,而以前会超时。
此外,类型检查器改进了对包含其他字面量表达式的嵌套数组字面量的性能。例如,以下无效代码以前会产生来自编译器的“在合理时间内解决过于复杂”的消息
enum E {
case first
case second
case third
}
let dictionary = [
.first: [0, 1, 2, 3, 4, 5, 6, 7],
.second: [8, 9, 10, 11, 12, 13, 14, 15],
.third: [16, 17, 18, 19, 20, 21, 22, 23],
]
Swift 5.4 代码现在使用精确的错误消息将此代码诊断为无效
error: reference to member 'first' cannot be resolved without a contextual type
.first : [ 0, 1, 2, 3, 4, 5, 6, 7],
^
error: reference to member 'second' cannot be resolved without a contextual type
.second : [ 8, 9, 10, 11, 12, 13, 14, 15],
^
error: reference to member 'third' cannot be resolved without a contextual type
.third : [16, 17, 18, 19, 20, 21, 22, 23],
^
类型检查器现在改进了结果构建器的诊断,包括无效语句(例如无效的 return 语句)、引用无效声明和模式匹配错误。例如
import SwiftUI
struct ContentView: View {
@State private var condition = false
var body: some View {
Group {
if condition {
Text("Hello, World!")
.frame(width: 300)
} else {
return Text("Hello, World!")
}
}
}
}
对于此代码,类型检查器将报告以下错误,并提供删除 return 以应用结果构建器的 Fix-It
error: cannot use explicit 'return' statement in the body of result builder 'SceneBuilder'
return Text("Hello, World!")
^
调试
在 Apple 平台上调试 Swift 代码时,具有弹性类型的变量(包括 Foundation 值类型,例如 URL、URLComponents、Notification、IndexPath、Decimal、Data、Date、Global、Measurement 和 UUID)再次显示在 Xcode 变量视图和 frame variable / v 命令中。