Swift 5.8 新特性
- Published on
- Authors
- Name
- zzzwco
- @zzzwco
Table of Contents
Xcode 14.3
Swift 5.8
SE-0365)
闭包内隐式调用 self(class Timer {
var eventHandler: (() -> Void)?
func start() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.eventHandler?()
}
}
}
class ViewController {
let timer = Timer()
init() {
timer.eventHandler = { [weak self] in
guard let self else { return }
// 如果已使用 [weak self] 捕获了 self 并且解包
// 则无需显式调用 self
doSomething()
}
timer.start()
}
func doSomething() {
print("Doing something...")
}
}
集合类型支持向下类型转换
class A {}
class A1: A {}
class A2: A {}
func downcast(arr: [A]) {
switch arr {
case let a1 as [A1]:
print("arr is [A1]: \(a1)")
case let a2 as [A2]:
print("arr is [A2]: \(a2)")
default:
print("Unknown collection type")
}
}
Swift 5.8 以前,以上的代码无法通过编译。需要这样写才可以:
if let a1 = arr as? [A1] {
//...
}
#file 与 #filePath
#file
不再输出完整的文件路径,而是以 <module-name>/<file-name>
的格式输出。
如果需要输出完成的文件路径名,使用 #filePath
。
print(#file)
print(#filePath)
// MagicFile/0274-magic-file.swift
// /Users/becca/Desktop/0274-magic-file.swift
这一特性目前默认是未开启的,需要在 Xcode 工程设置的 Other Swift Flags 中添加 -enable-upcoming-feature ConciseMagicFile
以开启该特性。
此外,根据 SE-0274/Concise magic file names 的描述,#file
还有利于优化二进制文件的大小和性能。
SE-0376)
@backDeployed(before:) 属性(@backDeployed(before:)
属性允许软件新版本的功能在旧版本上使用,换言之,当前版本可以使用未来版本的新功能。
如下,在 macOS 12 中定义了 Temperature 类型的结构体,在 macOS 13 时新增了一个计算属性 degreesFahrenheit
。理论上来说,macOS 12 是无法使用这个属性的。但使用 @backDeployed
之后,macOS 12 上就可以使用这个当前版本并不存在的计算属性了。
@available(macOS 12, *)
public struct Temperature {
public var degreesCelsius: Double
// ...
}
extension Temperature {
@available(macOS 12, *)
@backDeployed(before: macOS 13)
public var degreesFahrenheit: Double {
return (degreesCelsius * 9 / 5) + 32
}
}
当使用 @backDeployed
标记某个功能时,编译器会在运行时检查当前版本是否包含该功能。如果有,则直接调用。如果没有,则会拷贝一个副本以供使用。
@backDeployed
目前只能用于函数、方法、下标以及计算属性。比如下面是 iOS 16.4 新增的两个修饰器方法:
public func presentationCornerRadius(_ cornerRadius: CGFloat?) -> some View
public func presentationBackgroundInteraction(_ interaction: PresentationBackgroundInteraction) -> some View
presentationCornerRadius
是可以通过 @backDeployed
在 iOS 16.4 版本之前使用的,而另一个方法则不行,因为 PresentationBackgroundInteraction
是 iOS 16.4 才引入的新类型。
SE-0373)
解除结果生成器中变量的使用限制(现在可以在结果生成器中使用计算属性、lazy 变量,使用属性包装器修饰的变量等。
struct ContentView: View {
var body: some View {
lazy var v1: Int = .random(in: 0...10)
var v2: Int { v1 * v1 }
Text("v1: \(v1)") +
Text("v2: \(v2)")
}
}
支持 Swift-DocC 生成关于 extensions 的文档
此前使用 Swift-DocC 生成文档时,会忽略 extensions 中的内容。从 Swift-DocC plugin 1.2 和 Swift 5.8 开始,可以添加命令行参数生成关于 extensions 部分的文档。