Swift 5.4 正式发布,The Swift Programming Language 更新
Swift 5.4 现已正式发布,该版本包含各种语言和工具方面的改进。Swift 5.4 版本的 《The Swift Programming Language》也已更新,可以在 https://docs.swift.org/swift-book/ 和 Apple Books store 免费查看。
语言更新
Swift 5.4 包含以下新语言功能:
• 支持函数,下标和初始化程序中的多个可变参数(SE-0284)
• 扩展隐式成员语法(SE-0287)
• Result 生成器(SE-0289)
• 支持重载的本地函数
• 局部变量的属性包装器
同时为了为新的并发模型做准备,编译器现在会在将 await 作为标识符时发出警告并进行修复。这些标识符在 SE-0296 的以后版本的 Swift 中将被解释为关键字 await。
运行时性能和代码大小的改进
在 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 Package Manager更新
Swift Package Manager 在 Swift 5.4 中有几个重要更新:
• 现在,指定 5.4 工具版本的 Swift 软件包可以显式地将目标声明为可执行文件,从而允许在软件包代码中使用 @main
关键字(SE-0294)
• Windows 现已支持 Swift Package Manager
• Swift Package Manager 基于每个用户缓存软件包依赖关系,这减少了网络流量,并提高了对于相同软件包的后续使用的依赖关系解析的性能
• 现在,自动测试发现是所有平台上的默认设置,无需再使用 LinuxMain.swift
(已弃用)
• 对依赖项解析基础结构的多项改进,包括清单加载和缓存方面的改进,从而提高了依赖项解析的性能
• 改进的诊断基础架构和错误消息,导致针对依赖项解决问题及其他原因的更具操作性的错误消息
Windows平台支持
在 Windows 上对 Swift 的支持已经在几个重要方面取得了进展:
• Swift Package Manager现在可以在 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
版函数建议
• 在 $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毫秒内完成操作,之前该操作可能会超时。
此外,类型检查器还提高了包含其他文字表达式的嵌套数组文字的性能。例如,以下无效代码以前会在编译器中产生“too complex to solve in reasonable time”的消息:
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!")
}
}
}
}
对于这段代码,类型检查器将报告以下错误,以及修复它的Fix-It,以删除 return
以应用结果构建器:
error: cannot use explicit 'return' statement in the body of result builder 'SceneBuilder'
return Text("Hello, World!")
^
调试
在 Apple 平台上调试 Swift 代码时,具有弹性类型(包括诸如URL,URLComponents,Notification,IndexPath,Decimal,Data,Date,Global,Measurement和UUID等基础值类型)的变量将再次显示在 Xcode 变量视图和 frame variable / v
命令结果中。