Swift 5.9 新特性
- Published on
- Authors
- Name
- zzzwco
- @zzzwco
Xcode 15.0 beta
Swift 5.9
注:Swift 5.9 目前并未正式发布,本文会在正式发布后再次更新。
SE-0380)
if 和 switch 表达式(let s1 = if Bool.random() { "YES" } else { "NO" }
let s2 = switch Bool.random() {
case true: "YES"
case false: "NO"
}
SE-0393)
值和类型参数包(值和类型参数,实现了对不同类型的值和类型的抽象化,这是在 Swift 中实现可变泛型的第一步。
此前,泛型函数需要固定数量的类型参数。对于有多个参数的情况,通常使用函数重载来实现。这不仅在声明上很繁琐,在调用时也受到了参数数量的限制。
而有了参数包支持任意数量的不同类型参数,而且写法更加简洁。
比如下面的示例代码演示了将不同类型的可变参数组合成元组:
struct Pair<First, Second> {
var first: First
var second: Second
}
// each First, each Second 是两个类型的参数包
func makePairs<each First, each Second>(
firsts first: repeat each First, // 参数包扩展,可以传入可变参数
seconds second: repeat each Second
) -> (repeat Pair<each First, each Second>) {
// 从参数包扩展 first 和 second 中各取一个值构建 Pair
// 所有的 Pair 实例构成一个元组并返回
return (repeat Pair(first: each first, second: each second))
}
let pairs = makePairs(firsts: 1, "hello", "world", seconds: true, 1.0, false)
// 'pairs' is '(Pair(1, true), Pair("hello", 2.0), Pair("world", false))'
SE-0381)
可丢弃的任务组(withTaskGroup
和 withThrowingTaskGroup
用于创建任务组,任务组会保留整个子任务对象及其产生的数据,直到我们使用异步迭代或者调用 next()
方法消费掉某个子任务,任务组才会丢弃子任务及其产生的数据。而且 next()
方法还有个副作用,它会暂停任务的执行。
以上缺陷导致任务组不适用于需要长时间运行的子任务,比如在服务端运行的监听任务。因此 Swift 5.9 引入了 withDiscardingTaskGroup
和 withThrowingDiscardingTaskGroup
来解决这个问题,它们内部创建的子任务一旦完成就会被自动丢弃和销毁。
try await withThrowingDiscardingTaskGroup() { group in
while let newConnection = try await listeningSocket.accept() {
group.addTask {
handleConnection(newConnection)
}
}
}
宏(Macros)
Swift 5.9 引入了一个新的宏系统,用于减少样板代码和在编译期排除潜在的错误。
宏有两种表现形式:独立的宏和附属宏。独立的宏总是以 #
开头,比如下面要提到的 #email
,附属宏总是以 @
开头,比如 @Observable
。如果一段代码中没有这两个标志性的符号,那么可以确定没有宏。
自定义宏必须在 Package 中实现,最新的 Xcode 15 支持创建 Swift Macro:*File > New > Package…。*Package 的目录结构如下:
├── Package.swift
├── Sources
│ ├── WWDC23
│ │ └── WWDC23.swift // 向外公开 API
│ ├── WWDC23Client
│ │ └── main.swift // 运行和测试
│ └── WWDC23Macros
│ └── WWDC23Macro.swift // 宏的实现
└── Tests
└── WWDC23Tests
└── WWDC23Tests.swift // 测试
新建的 Package 已经实现了一个名为 #stringify
的独立宏,并且附有完整的测试和运行代码。 我们可以仿照它写一个名为 #email
的宏来检测一个字符串是否为有效的 email 地址,具体实现见源码。
根据宏的作用,它可以分为以下几类,其中前两个是独立宏,其它则为附属宏:
在 SwiftUI 开发中,我们将会大量的使用新框架 Observation 中的 @Observable,它是附属宏的典型运用之一。另一个新框架 SwiftData 中的 @Model,也展现出了宏的强大和简洁。
宏非常易于使用,但实现上比较复杂。值得庆幸的是,我们可以在 Xcode 查看宏的注释,而且可以展开宏来查看宏的具体实现和进行断点调试。
关于宏的使用,有待进一步探究。
所有权(Ownership)
待更新
其它
Result builders 可以更快更准确地给出错误提示,这有利于提高 SwiftUI 代码的编写效率。
Swift Foundation 提高了关于日期、日历计算的效率,并且极大地提高了 JSON 编码的处理速度。
更多关于 Swift 5.9 的更新内容,请移步官方 CHANGELOG 。