允许列表中的尾部逗号(SE-0439)
现在数组、字典、元组、函数调用、泛型参数、字符串插值以及由括号、方括号[]
或尖括号约束的项目列表的任何位置都允许使用尾随逗号,提升多行代码的可维护性。
// 参数列表尾部逗号
func add<T: Numeric>(_ a: T, _ b: T,) -> T {
a + b
}
// 数组尾部逗号
let numbers = [1, 2, 3,]
应用场景:多行参数列表时,调整顺序或注释某行不会破坏语法:
message.range(
of: "impossible",
options: .caseInsensitive, // 注释此行无需删除逗号
)
元类型KeyPath(SE-0438)
KeyPath现在支持访问类型的静态属性。
struct WarpDrive {
static let maxSpeed = 9.975 // 静态属性
var currentSpeed = 8.0
}
// 访问实例属性
let currentSpeed = \WarpDrive.currentSpeed
// 访问静态属性的键路径
// KeyPath<WarpDrive.Type, Double>
let maxSpeedKeyPath = \WarpDrive.Type.maxSpeed
let specificType: KeyPath<WarpDrive.Type, Double> = .maxSpeed
任务组子任务结果类型推断(SE-0442)
withTaskGroup
和 withThrowingTaskGroup
可自动推断子任务返回类型,无需显式声明 of:
。
func fetchMessages() async -> String {
await withTaskGroup { group in // ✅ 无需 of: String.self
group.addTask { "Hello" }
group.addTask { "World" }
var collected = [String]()
for await value in group {
collected.append(value)
}
return collected.joined(separator: " ")
}
}
使用 nonisolated
避免全局 Actor 推断(SE-0449)
nonisolated
现可用于类型声明,避免从协议继承的全局 Actor 隔离。
@MainActor
protocol DataStoring { /* ... */ }
// 不使用`nonisolated`,App会默认继承MainActor,调用controller.load的时候不用写await
struct App: DataStoring {
let controller = DataController()
init() {
controller.load()
}
}
// 使用nonisolated之后,在调用Actor修饰的方法,就需要显示使用await
nonisolated struct App2: DataStoring { // ✅ 退出主 Actor 隔离
init() async {
await controller.load() // 需显式 await
}
}
成员导入可见性(SE-0444)
模块的扩展成员不再隐式传递到其他文件,需显式导入。
问题示例:
若 Maps
和 GeoKit
模块都扩展了 Double.toRadians()
,旧版本可能导致冲突。
解决方案:
在需要的文件中显式导入模块。并且开启MemberImportVisibility
编译器警告精细控制(SE-0443)
通过诊断组(Diagnostic Groups)控制特定警告的行为。
操作步骤:
- 添加编译器标志
-print-diagnostic-groups
。 - 根据输出的诊断组名(如
[DeprecatedDeclaration]
)控制警告级别:
-Werror DeprecatedDeclaration # 将弃用警告转为错误
-Wwarning=DeprecatedDeclaration # 保持为警告(即使全局开启 Treat Warnings as Errors)
测试框架改进(ST-0005, ST-0006, ST-0007)
范围确认(ST-0005)
@Test func testNewsLoader() async {
await confirmation(expectedCount: 5...10) { confirm in
for await _ in NewsLoader() {
confirm() // 确认调用次数在 5-10 次之间
}
}
}
错误断言改进(ST-0006)
@Test func testPlayGame() {
let error = #expect(throws: GameError.self) {
try playGame(at: 22)
}
#expect(error == .disallowedTime) // 直接验证错误类型
}
测试作用域(ST-0007)
struct PlayerTestTrait: TestScoping {
func provideScope(/*...*/) async throws {
try await Player.$current.withValue(customPlayer) {
try await function() // 在此作用域内运行测试
}
}
}
@Test(.playerTestTrait) func testCustomPlayer() { /* ... */ }
其他改进
- 跨平台编译优化(SE-0387) :简化跨平台编译(如 Apple Silicon 编译 x86 Linux 程序)。
- Objective-C 实现替换(SE-0436) :允许 Swift 覆盖 Objective-C 方法实现。
- 包管理器可选特性(SE-0450) :包可声明可选特性(如实验性 API),使用者按需启用。
总结
Swift 6.1 主要聚焦于语法便利性(尾部逗号、类型推断)、并发安全(nonisolated
)、模块可见性、测试框架增强和编译器控制。虽然无重大变革,但多项改进显著提升开发体验,为 Swift 6.2 的更大更新奠定基础。