Swift 5.9 内置于 Xcode 15,虽然是 Swift 5 的最后一个大版别,依然增加了不少新特性。
if与switch表达式
if
与switch
语句能够作为表达式运用。
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:
"优异"
default:
"其他"
}
print(result2)
~Copyable不行仿制
- 引入了“不行仿制的枚举与结构体”的概念。
- 不行仿制的枚举与结构体需求恪守
~Copyable
协议。 - 枚举与结构体假如恪守了
~Copyable
协议,则除了Sendable
协议再也不能恪守其他任何协议。
struct Person: ~Copyable {
var name = "Zhangsan"
var age = 10
let sex = "male"
}
let person = Person()
print(person.name, person.age, person.sex)
// 报错: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))
// 应用于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...")
}
// 异步函数
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 引入了一个重要新功能 — 宏。
- 宏能够在编译前动态地操作代码,从而能够在编译时注入额外的功能。
分类
- 独立 Macro:经过
@freestanding
关键字声明,运用时以标签#
最初,并在后边的()
中增加对应的参数,首要作用是代替代码中的内容。 - 附加 Macro:经过
@attached
关键字声明,运用时以标签@
最初,并在后边的()
中增加对应的参数,首要作用是为声明增加代码。
运用步骤
- 每个 Macro 都是 Package,因而需求经过 Xcode 菜单 —> File —> New —> Package… —> Swift Macro 创立 Macro Package。
-
Sources
:源码目录包括 3 个子文件夹。-
[Macro name]
:包括创立 Macro 的声明源文件。 -
[Macro name]Client
:包括创立 Macro 的运用源文件。 -
[Macro name]Macros
:包括创立 Macro 的完成源文件。
-
- 在运用 Macro 的当地,能够经过选中宏 —> 右键菜单 —> Expand Macro 在下方显示打开后的代码。
// 声明源文件 [Macro name].swift
// 定义一个宏函数,接收一个泛型参数,回来原始值与对应字符串组成的元组,函数完成在FirstMacroMacros的StringifyMacro
@freestanding(expression)
public macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "FirstMacroMacros",
type: "StringifyMacro")
// 完成源文件 [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))"
}
}
// 导出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)\"")