Swift 5.9 內(nèi)置于 Xcode 15,雖然是 Swift 5 的最后一個(gè)大版本,仍然增加了不少新特性。
if與switch表達(dá)式
if與switch語句可以作為表達(dá)式使用。
let score = 90
let result1 = if score >= 60 {
"及格"
} else {
"不及格"
}
print(result1)
let result2 = switch score {
case 0 ..< 60:
"不及格"
case 60 ..< 70:
"及格"
case 70 ..< 80:
"中等"
case 89 ..< 90:
"良好"
case 90 ... 100:
"優(yōu)秀"
default:
"其他"
}
print(result2)
~Copyable不可復(fù)制
- 引入了“不可復(fù)制的枚舉與結(jié)構(gòu)體”的概念。
- 不可復(fù)制的枚舉與結(jié)構(gòu)體需要遵守
~Copyable協(xié)議。 - 枚舉與結(jié)構(gòu)體如果遵守了
~Copyable協(xié)議,則除了Sendable協(xié)議再也不能遵守其他任何協(xié)議。
struct Person: ~Copyable {
var name = "Zhangsan"
var age = 10
let sex = "male"
}
let person = Person()
print(person.name, person.age, person.sex)
// 報(bào)錯(cuò):Cannot consume noncopyable stored property 'person' that is global
let personCopy = person
print(personCopy.name, personCopy.age, personCopy.sex)
Clock增加sleep(for:)方法
let clock1 = ContinuousClock()
try? await clock1.sleep(for: .seconds(1))
let clock2 = SuspendingClock()
try? await clock2.sleep(for: .seconds(1))
// 應(yīng)用于Concurrency
Task {
print("start task...")
// Swift5.7之后,Swift5.9之前
try await Task.sleep(until: .now + .seconds(1), clock: .suspending)
// Swift5.9之后
try await Task.sleep(for: .seconds(1), clock: .suspending)
print("continue task...")
}
// 異步函數(shù)
func doSomeAsyncWork() async throws {
print("start to work...")
// Swift5.7之后,Swift5.9之前
try await Task.sleep(until: .now + .seconds(3), clock: .continuous)
// Swift5.9之后
try await Task.sleep(for: .seconds(3), clock: .continuous)
print("continue to work...")
}
Macros
介紹
- Swift 5.9 引入了一個(gè)重要新功能 — 宏。
- 宏可以在編譯前動(dòng)態(tài)地操作代碼,從而能夠在編譯時(shí)注入額外的功能。
分類
- 獨(dú)立 Macro:通過
@freestanding關(guān)鍵字聲明,使用時(shí)以標(biāo)簽#開頭,并在后邊的()中添加對(duì)應(yīng)的參數(shù),主要作用是代替代碼中的內(nèi)容。 - 附加 Macro:通過
@attached關(guān)鍵字聲明,使用時(shí)以標(biāo)簽@開頭,并在后邊的()中添加對(duì)應(yīng)的參數(shù),主要作用是為聲明添加代碼。
使用步驟
- 每個(gè) Macro 都是 Package,因此需要通過 Xcode 菜單 —> File —> New —> Package... —> Swift Macro 創(chuàng)建 Macro Package。
-
Sources:源碼目錄包含 3 個(gè)子文件夾。-
[Macro name]:包含創(chuàng)建 Macro 的聲明源文件。 -
[Macro name]Client:包含創(chuàng)建 Macro 的使用源文件。 -
[Macro name]Macros:包含創(chuàng)建 Macro 的實(shí)現(xiàn)源文件。
-
- 在使用 Macro 的地方,可以通過選中宏 —> 右鍵菜單 —> Expand Macro 在下方顯示展開后的代碼。
// 聲明源文件 [Macro name].swift
// 定義一個(gè)宏函數(shù),接收一個(gè)泛型參數(shù),返回原始值與對(duì)應(yīng)字符串組成的元組,函數(shù)實(shí)現(xiàn)在FirstMacroMacros的StringifyMacro
@freestanding(expression)
public macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "FirstMacroMacros",
type: "StringifyMacro")
// 實(shí)現(xiàn)源文件 [Macro name]Macro.swift
public struct StringifyMacro: ExpressionMacro {
public static func expansion(
of node: some FreestandingMacroExpansionSyntax,
in context: some MacroExpansionContext
) -> ExprSyntax {
guard let argument = node.argumentList.first?.expression else {
fatalError("compiler bug: the macro does not have any arguments")
}
return "(\(argument), \(literal: argument.description))"
}
}
// 導(dǎo)出Macro以供使用
@main
struct FirstMacroPlugin: CompilerPlugin {
let providingMacros: [Macro.Type] = [
StringifyMacro.self,
]
}
// 使用源文件 main.swift
import FirstMacro
let a = 10
let b = 20
let (result, code) = #stringify(a + b)
print("The value \(result) was produced by the code \"\(code)\"")