Ziglings 笔记 27: 让代码“迟到”的 Defer
离开前的最后这就是
在 Ziglings 的第 27 个练习中,我接触到了 Zig 极其重要的一个关键字:defer。
如果你写过 Go 语言,你对它一定不陌生。但在 C 语言中,我们经常需要用 goto cleanup; 来处理函数退出前的资源释放。Zig 的 defer 让这一切变得异常优雅。
挑战:颠倒的时间
我们需要在代码中插入一句 defer,使得原本写在前面的打印语句,实际上在后面执行。
解决方案
这是代码实现:
const std = @import("std");
pub fn main() void {
// 关键点:defer 语句
// 这行代码不会立即执行,它被“推迟”到了 main 函数退出前的那一刻。
defer std.debug.print("Two\n", .{});
// 这行代码会先执行
std.debug.print("One ", .{});
}
// 输出顺序:
// 1. "One "
// 2. (函数结束前) "Two\n"
核心知识点总结
1. 作用域守门员
defer 绑定的代码会在当前代码块(Block)退出时执行。这就像是你出门前贴在门把手上的便以此条:“出门记得关灯”。无论你是高兴地走出门,还是因为着火了慌忙逃出门(报错返回),你都会看到这张便条。
2. 栈式执行 (LIFO)
虽然这个练习只用了一个 defer,但如果在一个函数里写了多个 defer,它们会按照 后进先出 (Last In, First Out) 的顺序执行。
defer print("1");
defer print("2");
// 结果会先打印 2,再打印 1
这非常符合逻辑:我们要先释放最近获取的资源(比如内部锁),再释放最早获取的资源(比如外部连接)。
3. 为什么它很重要?
这个特性彻底解决了 C 语言中常见的资源泄漏问题。我们可以在分配资源(malloc/open)的那一刻,就立即在下一行写上 defer 释放它。这样,资源的生命周期管理就在视觉上闭环了,极大降低了心智负担。
后续预告:既然 defer 这么好用,那我们是不是可以用它来自动清理内存或者关闭文件?下一篇练习将展示 defer 在多重资源管理中的实际威力。