defer、错误与提前返回
即使抛出错误或提前返回,也确保完成清理。
defer、错误与提前返回 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
延迟执行在返回时运行
即使函数通过 return 提前退出,defer 代码块仍会运行。
func check(_ value: Int) {
defer { print("cleanup ran") }
if value < 0 {
print("negative, returning early")
return
}
print("value is", value)
}
check(-5)每条路径都会清理
无论哪个 return 被执行,延迟清理都会准确运行一次。
func classify(_ n: Int) {
defer { print("done classifying") }
if n == 0 { print("zero"); return }
if n > 0 { print("positive"); return }
print("negative")
}
classify(0)延迟执行在抛出错误时运行
函数抛出错误时,已注册的延迟执行仍会在作用域展开退出的过程中运行。
enum MyError: Error { case bad }
func risky(_ fail: Bool) throws {
defer { print("cleanup on the way out") }
if fail { throw MyError.bad }
print("no failure")
}
try? risky(true)结合返回与抛出错误
无论函数正常返回还是抛出错误,同一个延迟执行都会运行。
enum E: Error { case oops }
func op(_ flag: Bool) throws -> Int {
defer { print("op finishing") }
if flag { throw E.oops }
return 42
}
let r = try? op(false)
print(r ?? -1)错误传播前进行清理
延迟执行会在抛出的错误到达调用者之前运行,因此资源会先被释放。
enum E: Error { case fail }
func load(_ broken: Bool) throws {
print("open")
defer { print("close") }
if broken { throw E.fail }
print("read")
}
do {
try load(true)
} catch {
print("caught:", error)
}使用延迟执行保护
一种常见模式是:获取资源、延迟执行清理,然后使用 guard 提前返回;这些提前返回仍会触发清理。
func process(_ items: [Int]) {
print("start")
defer { print("finished") }
guard !items.isEmpty else {
print("nothing to do")
return
}
print("processing", items.count, "items")
}
process([])延迟执行与抛出错误的循环
循环中的延迟执行会在每次迭代结束时运行,即使后面的语句抛出了错误。
enum E: Error { case stop }
func loop() throws {
for i in 1...3 {
defer { print("end", i) }
if i == 2 { throw E.stop }
print("body", i)
}
}
try? loop()提前返回时的顺序
提前返回时,多个延迟执行仍会按 LIFO 顺序运行。
func multi(_ skip: Bool) {
defer { print("A") }
defer { print("B") }
if skip { return }
print("body")
}
multi(true)失败时记录日志
使用延迟执行,可以在所有退出路径上统一记录完成或失败信息。
enum E: Error { case bad }
func attempt(_ fail: Bool) throws {
var success = false
defer { print("attempt success:", success) }
if fail { throw E.bad }
success = true
}
try? attempt(true)抛出错误时恢复状态
操作抛出错误时,延迟执行非常适合回滚临时状态。
enum E: Error { case fail }
func transaction(_ fail: Bool) throws {
var inProgress = true
defer { inProgress = false; print("inProgress:", inProgress) }
if fail { throw E.fail }
print("committed")
}
try? transaction(true)最佳实践
对于必须在提前返回和抛出错误后仍执行的清理,请依靠 defer,这样任何退出路径都不会造成资源泄漏。
enum E: Error { case x }
func safe(_ fail: Bool) throws {
print("acquire")
defer { print("release") }
if fail { throw E.x }
print("use")
}
try? safe(true)快速检查
测试延迟执行在错误和返回情况下的行为。
回顾
defer 会在每次作用域退出时运行,包括提前执行 return 和抛出错误的情况,并且会在错误传播之前执行。这使它成为在所有退出路径上进行清理和恢复状态的可靠位置,同时保留 LIFO 顺序。
func f(_ skip: Bool) {
defer { print("cleanup") }
if skip { return }
print("work")
}
f(true)用 AI 导师学习 Swift — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 122
- 课程
- 409
常见问题解答
「defer、错误与提前返回」课时是免费的吗?
是的 — 「defer、错误与提前返回」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「defer、错误与提前返回」这节课中我会学到什么?
即使抛出错误或提前返回,也确保完成清理。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「defer、错误与提前返回」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- defer 的工作原理
- 多个 defer 代码块的执行顺序
- 使用 defer 清理资源
- defer、错误与提前返回