真实世界的 Zig — FileGuard 项目全解剖
真实世界的 Zig — FileGuard 项目全解剖
全书收官:把前十二章的零件总装成一个真实项目——FileGuard, 一个命令行文件监控工具。 它的价值不在工具本身,而在过程: 架构决策怎么权衡(为什么不用 OS 文件事件 API)、内存责任怎么落 (每个 errdefer 对应哪笔账)、C 互操作怎么救场(@cImport 借 fnmatch)、 依赖怎么锁(zon 里的 commit 哈希)。读完这一章,前面所有章节都有了着落点。
1. 这一章讲什么
第三部分的布局:第 12 章给高级特性,这一章把它们连同全部基础知识一起 用在一个项目上。FileGuard 监控目录:发现文件的创建、删除、修改、移动, 输出人类可读的报告。它是「能拿去给同事看」的那种项目,也是原书留给你的 脚手架——每个模块都留了「professional 扩展」的方向。
2. 顶层全景:架构与数据流
cli.zig 解析参数 → CliOptions(含 -i/-x/-d/-c 等简写)
│
config.zig 两份配置结构:TraversalConfig 管遍历,DetectionConfig 管检测
│ (CLI 选项在这里翻译成引擎的语言,引擎不知道命令行的存在)
▼
traversal.zig 递归走目录,按 glob 过滤(include 优先于 exclude)
│ ├─ pattern.zig:@cImport 借 C 的 fnmatch 做模式匹配
│ └─ max_depth 防止符号链接环 + 栈溢出
▼
file_index.zig FileIndex:两个哈希表
│ ├─ files: 路径 → FileMetadata
│ └─ inodes: inode → 路径 ← 移动检测的关键
▼
change_detection.zig 旧索引 vs 新索引 → ChangeJournal
│ ├─ 旧有新无 → 查 inode → 有 = moved,无 = deleted
│ └─ 新有旧无 → 查 inode → 非移动 = created
▼
输出 / 更新基线(current 克隆为新基线,循环)
图说:两阶段(建基线 → 比对)是心脏;双索引是 FileGuard 比
「朴素工具」聪明的全部秘密。主线例子(贯穿全章,数字都是原书的):监控一个目录,里面有 a.txt;
把 a.txt 改名为 b.txt 再扫描一次——看 FileGuard 怎么报 MOVED 而不是
「删了一个、建了一个」。每一步旁边是具体的结构和 inode。
3. 核心设计决策:为什么这样设计
3.1 不用 inotify,用周期扫描
操作系统其实都提供文件事件:Linux 的 inotify、macOS 的 kqueue、 Windows 的 ReadDirectoryChangesW——但三家能力、怪癖、边界情况 (网络文件系统、高频变更)各不相同1。FileGuard 的选择:周期扫描 + 智能变更检测——跨平台行为一致、简单、可调试2。需要监测五件事: 多种变更类型、大目录的高效扫描、噪声过滤、智能的移动识别、可读的报告3。
3.2 两阶段检测与资源账
做法:先建一份基线索引(路径、大小、时间戳、inode), 之后每次扫描建新索引和基线比对,记录差异,然后基线换成新索引4。 只存元数据、不读内容,所以快;内容哈希(可选,默认关)加钱加准确度—— 性能文档照实写:内存随文件数线性涨,开哈希后磁盘 I/O 是主要开销5。
3.3 inode:移动检测的指纹
inode 是文件系统给每个文件的内部唯一编号,改名、移动都不变; Windows 的等价物叫 file ID6。所以:文件从 A 消失、同一个 inode 出现在 B, 就是「移动」而非「删除+新建」——不用比内容,快且可靠7。 原书的比方:文件名是公开化名,inode 是档案号——贴假胡子改名也骗不过档案8。
4. 模块解剖(每块对应前面哪章)
4.1 file_metadata.zig:第 9 章的实战答卷
FileMetadata 五个字段:md: fs.File.Metadata(std 代管的跨平台元数据,
Windows 时间从 1601 年算、Unix 从 1970 年算这类差异全被抹平9)、
path、inode、checksum: ?[]const u8(可选内容哈希)、allocator10。
三个方法各示范一个第 9 章的纪律:
- init:申请绝对路径后立即
errdefer allocator.free(abs_path)—— 后面任何一步失败,这笔记账都不会漏11; - deinit:free path 和 checksum;
md不 free,因为它是值类型不拥有内存12; - computeFileHash:SHA-256,4 KB 缓冲分块读——哈希 10 GB 视频 不需要 10 GB 内存13。
4.2 file_index.zig:双索引与深拷贝
FileIndex = files: StringHashMap(FileMetadata) + inodes: AutoHashMap(u64, []const u8) + 一个看起来多余的 path_storage: StringHashMap(void)。
第三个表的用途:hash map 的键是路径的拷贝,清理时需要「我们分配过哪些路径」的
清单——值类型 void 是零大小类型(第 9 章!),一份小簿记换清理逻辑的可靠14。
deinit 的顺序有讲究:先清抽屉里的东西,再拆柜子——先逐个 deinit 元数据、
free 路径,最后 deinit 三个 map 本身;顺序反了就是泄漏15。
addFile 里的 errdefer 链、clone 的深拷贝(每条路径、每个 checksum
都重新 dupe)——全是第 9 章 Sword 模式的复用16。
4.3 traversal.zig:递归 + @cImport 救场
目录遍历按 entry 类型分派:文件 → 过滤后入索引;目录 → 深度没超就递归; 符号链接 → 配置允许才跟(附带的危险:链接环 = 无限递归, max_depth 是安全阀)17。
模式匹配没有自己造轮子:@cImport 直接借 C 标准库的 fnmatch:
const c = @cImport({
@cInclude("stdlib.h");
@cInclude("fnmatch.h");
});
pub fn matches(pattern: []const u8, name: []const u8) bool {
const rc: c_int = c.fnmatch(pattern.ptr, name.ptr, 0);
return rc == 0;
}原书的点评一句话:「几十年的战斗测试过的代码,一个 @cImport 之遥」—— 这正是第 12 章 C 互操作的实战意义18。 过滤规则:exclude 永远优先于 include(「黑名单先于普通入场券」)19。
4.4 change_detection.zig:两表比对算法
ChangeType 枚举六个值:created / deleted / modified / moved /
permissions / timestamp——检测的词汇表20。
算法两遍扫描:
第一遍(旧索引):每个旧文件在新索引里查路径
├─ 在 → 第二遍处理
└─ 不在 → 用 inode 在新索引查
├─ 查到 → 记 .moved(旧路径 → 新路径)
└─ 查不到 → 记 .deleted
第二遍(新索引):每个新文件在旧索引里查路径
├─ 在 → detectFileModifications(内容哈希 > 大小 > 权限 > 时间戳)
└─ 不在 → inode 在旧索引查得到 = 移动的目的地(跳过),否则记 .created回到主线例子:基线里有 a.txt(inode 1234);改名 b.txt 后新索引里
没有 a.txt、b.txt 的 inode 恰是 1234 → 第一遍报 MOVED a.txt → b.txt,
第二遍认出 b.txt 是移动目的地、不再报 created。一次改名,一条准确的记录,
而不是一对误导的删除+创建21。
4.5 cli.zig 与主循环
CLI 用一个外部库 zig-args(argsParser.parseForCurrentProcess)解析参数,
CliOptions 给出全套默认值(监控时间戳和大小,不监控内容——性能优先)22。
run() 的第一步是立一个 GeneralPurposeAllocator(GPA),退出时
defer _ = gpa.deinit()——第 9 章的调试型分配器,泄漏会在退出时被它抓出来;
位置参数第一个是监控路径,缺省当前目录 .23。
配置在 CLI 和引擎之间还有一次翻译:runMonitor 把 CliOptions 拆成
两份引擎配置——TraversalConfig(max_depth、include/exclude、
hash_content、follow_symlinks)交给遍历器,DetectionConfig
(monitor_timestamps/size/content/permissions、detect_moves)交给检测器。
引擎模块只认这两份结构、不知道命令行长什么样——这是原书模块分工里
config.zig 的存在理由:将来加 GUI 或配置文件,核心引擎一行不用动24。
主循环(单次或 --continuous 模式):每轮新建 current_index → 遍历 →
detectChanges → 有变化就打印并克隆 current 为新基线;
遍历出错时连续模式「睡一觉下轮重试」,单次模式直接上报25。
validatePath 按错误类型给人类可读的报错(FileNotFound / AccessDenied),
而不是扔个裸错误26。
4.6 构建与依赖:第 11 章的复用照单
build.zig:createModule + addExecutable + exe.linkLibC()
(fnmatch 需要)+ b.dependency("args", ...) + addImport27。
build.zig.zon 里锁依赖到 commit 哈希:
.args = .{
.url = "git+https://github.com/ikskuh/zig-args?ref=master#9425b94c...", // 原书示例 URL(查阅于 2026-10-19)
.hash = "args-0.0.0-CiLiqv_NAAC97fGpk9hS2K681jkiqPsWP6w3ucb_ctGH",
},原书的理由:不说「给我最新版」,而是钉死一个 commit(该 URL 为原书示例,查阅于 2026-10-19)**——「能工作一次, 就该永远工作,没有神秘的『昨天还好好的』」28。
5. 专业扩展与项目方向(章末的「出去之后」)
原书给 FileGuard 列的生产级增强:机器可读输出(JSON/CSV)、写日志文件、 通知(邮件/Slack)、过滤掉 .DS_Store 之类的噪声、检出变更时跑钩子命令29。 另有一份架构级扩展清单,面向「从练手到生产」的跳跃:数据库后端 (存元数据与变更历史,做长期分析)、Web 仪表盘、插件系统(用户自定义 变更处理)、跨机分布式监控(集中上报)、安全增强(检出可疑变更)30。
十个练手项目方向(照原书清单,挑最常见的说):命令行搜索工具(grep 的更好用版)、 日志解析器、开发服务器 watcher、配置校验器、目录同步器、Markdown 转换器、 JSON/XML 处理器、文本处理瑞士刀、HTTP 客户端、构建产物清理器。 选择的共同理由:吃 Zig 的速度红利、依赖少、错误处理明确31。
社区资源(原书清单):Zig Showtime(Loris Cro 的视频系列)、Zig Discord (最活跃的枢纽)、Ziggit 论坛、GitHub 主仓、r/Zig32。 贡献路径:核心语言、文档、包、工具链、教育 advocacy33。
路线图(写作时):自举编译器(从 C++ 编译器迁到全 Zig 编写)、包管理器、 内存管理增强、互操作增强、性能优化、新 Async I/O、懂 comptime 的 语言服务器34。生产案例:Bun(JS 运行时)、TigerBeetle(分布式金融账务数据库)、 MachEngine(游戏引擎)、microzig(嵌入式)、各类 WASM 项目35。
判断(我们的,不是书里的): FileGuard 这一章是全书教学成色最高的一章—— 不是因为代码难,而是因为它诚实地展示了「工程权衡如何落到代码上」: 不用 inotify 是权衡(简单可调试 > 事件驱动的新鲜感); 内容哈希默认关是权衡(性能 > 彻底);path_storage 的冗余表是权衡 (一点内存 > 清理逻辑的脆弱)。每个权衡都在注释里留了「为什么」。 这正是第 1 章「透明」哲学的成熟形态:连决策过程都不藏。 如果错,会错在: 周期扫描在超高频变更场景(日志目录每秒上千次写) 会漏事件或性能劣化——原书没给这个边界;以及符号链接的重复计数问题被 一句「为简化接受」带过,真实使用要补 visited-inode 去重。
6. 作者的判断与证据
可核的: 全部代码结构、八模块分工(含 pattern.zig 与 config.zig)、双索引设计、构建文件与 zon 的锁哈希、 案例名单(Bun/TigerBeetle 等)2835。
立场: 「周期扫描优于平台事件 API」是有争议的工程选择(高频场景不然), 原书给了理由但没有给反方;「钉死 commit 哈希」被奉为可复现性的圭臬, 代价(安全更新要靠手动 bump 每个依赖)没有被提及。
7. 边界与局限
| 缺什么 | 说明 |
|---|---|
| 没有单元测试的展示 | FileGuard 各模块的 test 块一个没贴——第 7 章的纪律在收官项目里缺席 |
| 符号链接环只靠 max_depth | visited-inode 去重被「为简化」放弃,深度不设限时仍有栈溢出风险 |
| args 库的使用一带而过 | zig-args 的 parseForCurrentProcess 细节没有,读者要自己读库的文档 |
| Windows 的 file ID 差异没展开 | 「works slightly differently」一句带过 |
| 连续模式的 Ctrl+C 处理(should_exit)没实现 | 代码里引用了 should_exit 但注释说省略,实际信号处理留给读者 |
| 案例名单无引用 | Bun/TigerBeetle 等的介绍无任何来源标注(补充:均为公开知名项目) |
7.5 原书第十四章:一句话交代
原书的「Chapter 14: Unlock Your Book's Exclusive Benefits」是 Packt 的购书福利广告页(在线阅读器、AI 助手、DRM-free 下载),没有任何技术内容。覆盖纪律上在此登记一行:已读、无机制可拆、不引。
8. 可带走的
主线例子一行: 基线里有 a.txt(inode 1234)→ 改名 b.txt →
新索引无 a.txt 但 b.txt 的 inode = 1234 → 报 MOVED a.txt → b.txt,
不报 deleted+created。
- 工程权衡要写进注释:为什么不用 inotify、为什么哈希默认关、 为什么有 path_storage——FileGuard 每个「奇怪」设计都有明写的理由;
- 两阶段索引是监控类工具的通用骨架:基线 → 快照 → 比对 → 换基线;
- 双索引(路径 + inode) 让「移动」从「删除+创建」中分离出来—— inode 是文件系统的指纹;
- 第 9 章的纪律在实战里的样子:init 申请即 errdefer、deinit 先内容后容器、 深拷贝每条路径、哈希分块读;
- @cImport 是正经生产力:glob 匹配直接借 C 的 fnmatch,「不重复造轮子」;
- CLI 三件套:外部 args 库解析 + 合理默认值 + 按错误类型给可读报错;
- 依赖锁 commit 哈希换可复现性,代价是手动跟进安全更新;
- 连续模式的服务器素养:遍历失败「下轮重试」,不让临时故障杀掉监控;
- 章末地图:10 个练手项目、社区五站、路线图六项、生产案例五个(Bun、 TigerBeetle、MachEngine、microzig、WASM 项目);
- 全书落点:「explicitness is a virtue, performance is a priority, and each allocation has a home to return to」36。
9. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 第三部分地图 | Part 3: Advanced Zig and Real-World Application | text/19-ch03-part-3-advanced-zig-and-real-world-application.txt:4(搜「elevate your Zig skills」) |
| 不用 inotify 的决策 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:102(搜「inotify」) · text/21-ch13-chapter-13-real-world-zig.txt:107(搜「periodic scanning」) |
| 监控需求五件 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:112(搜「Detect multiple types」) |
| 两阶段设计 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:133(搜「Two-Phase Change Detection」) |
| inode 与移动检测 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:144(搜「Inode Tracking」) · text/21-ch13-chapter-13-real-world-zig.txt:453(搜「secret identity card」) |
| 项目结构与模块分工 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:175(搜「fileGuard/」) · text/21-ch13-chapter-13-real-world-zig.txt:188(搜「distinct responsibility」) |
| FileMetadata 五字段 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:232(搜「pub const FileMetadata」) |
| init 的 errdefer | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:262(搜「realpathAlloc」) · text/21-ch13-chapter-13-real-world-zig.txt:295(搜「setting up a safety net」) |
| computeFileHash 分块 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:343(搜「Sha256.init」) · text/21-ch13-chapter-13-real-world-zig.txt:374(搜「10GB video file」) |
| 跨平台时间差(1601 vs 1970) | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:385(搜「100-nanosecond intervals」) |
| FileIndex 三表 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:422(搜「pub const FileIndex」) · text/21-ch13-chapter-13-real-world-zig.txt:445(搜「path_storage might seem redundant」) |
| deinit 顺序 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:507(搜「emptying the drawers」) |
| 遍历与符号链接 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:768(搜「traverseDirectory」) · text/21-ch13-chapter-13-real-world-zig.txt:841(搜「loops in what」) |
| fnmatch @cImport | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:724(搜「fnmatch.h」) · text/21-ch13-chapter-13-real-world-zig.txt:744(搜「battle-tested」) |
| exclude 优先 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:753(搜「Exclusion patterns take precedence」) |
| ChangeType 六值与检测算法 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:943(搜「pub const ChangeType」) · text/21-ch13-chapter-13-real-world-zig.txt:1028(搜「pub fn detectChanges」) · text/21-ch13-chapter-13-real-world-zig.txt:1121(搜「The magic here」) |
| 修改检测优先级 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1137(搜「highest priority」) |
| CLI 与简写 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1262(搜「pub const CliOptions」) · text/21-ch13-chapter-13-real-world-zig.txt:1290(搜「shorthands」) |
| GPA 与位置参数缺省 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1315(搜「GeneralPurposeAllocator」) · text/21-ch13-chapter-13-real-world-zig.txt:1334(搜「args.positionals」) |
| 配置结构:CLI→引擎翻译 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:696(搜「pub const TraversalConfig」) · text/21-ch13-chapter-13-real-world-zig.txt:1003(搜「pub const DetectionConfig」) · text/21-ch13-chapter-13-real-world-zig.txt:1422(搜「Create traversal configuration」) |
| 主循环与基线更新 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1475(搜「while (!should_exit)」) · text/21-ch13-chapter-13-real-world-zig.txt:1544(搜「new_baseline」) |
| validatePath | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1593(搜「validatePath」) |
| main.zig 极简 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1667(搜「try cli.run()」) |
| build.zig 与 linkLibC | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1681(搜「pub fn build(b: *std.Build)」) · text/21-ch13-chapter-13-real-world-zig.txt:1694(搜「linkLibC」) |
| zon 锁 commit 哈希 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1725(搜「ikskuh/zig-args」) · text/21-ch13-chapter-13-real-world-zig.txt:1748(搜「Instead, we specify an exact」) |
| 专业扩展清单 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1640(搜「Output Formats」) |
| 架构级扩展清单 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1784(搜「Database Backend」) · text/21-ch13-chapter-13-real-world-zig.txt:1791(搜「Security Enhancements」) |
| 十个项目方向 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1806(搜「Command-Line Search Tool」) |
| 社区资源 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1856(搜「Zig Showtime」) |
| 路线图 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1896(搜「Self-Hosted compiler」) |
| 生产案例 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1918(搜「Bun」) · text/21-ch13-chapter-13-real-world-zig.txt:1922(搜「TigerBeetle」) |
| 全书落点句 | Chapter 13: Real-World Zig | text/21-ch13-chapter-13-real-world-zig.txt:1946(搜「explicitness is a virtue」) |
Footnotes
-
出处:「Chapter 13: Real-World Zig」第 97–108 段(
text/21-ch13-chapter-13-real-world-zig.txt:102,搜「inotify」;text/21-ch13-chapter-13-real-world-zig.txt:103,搜「ReadDirectoryChangesW」)。 ↩ -
出处:同章第 106–108 段(
text/21-ch13-chapter-13-real-world-zig.txt:107,搜「periodic scanning」;text/21-ch13-chapter-13-real-world-zig.txt:108,搜「simple to understand and debug」)。 ↩ -
出处:同章第 110–123 段(
text/21-ch13-chapter-13-real-world-zig.txt:112,搜「Detect multiple types」)。 ↩ -
出处:同章第 133–143 段(
text/21-ch13-chapter-13-real-world-zig.txt:137,搜「baseline index」;text/21-ch13-chapter-13-real-world-zig.txt:139,搜「Record the differences」)。 ↩ -
出处:同章第 84–95 段(
text/21-ch13-chapter-13-real-world-zig.txt:89,搜「CPU impact remains minimal」;text/21-ch13-chapter-13-real-world-zig.txt:92,搜「disk I/O」)。 ↩ -
出处:同章第 144–155 段(
text/21-ch13-chapter-13-real-world-zig.txt:146,搜「inode number」;text/21-ch13-chapter-13-real-world-zig.txt:148,搜「file IDs」)。 ↩ -
出处:同章第 151–155 段(
text/21-ch13-chapter-13-real-world-zig.txt:152,搜「moved, not deleted and recreated」)。 ↩ -
出处:同章第 451–465 段(
text/21-ch13-chapter-13-real-world-zig.txt:453,搜「secret identity card」;text/21-ch13-chapter-13-real-world-zig.txt:458,搜「changing its alias」)。 ↩ -
出处:同章第 250–256 与 377–398 段(
text/21-ch13-chapter-13-real-world-zig.txt:243,搜「encapsulates platform-specific」;text/21-ch13-chapter-13-real-world-zig.txt:385,搜「100-nanosecond intervals」;text/21-ch13-chapter-13-real-world-zig.txt:387,搜「1970」)。 ↩ -
出处:同章第 228–256 段(
text/21-ch13-chapter-13-real-world-zig.txt:232,搜「pub const FileMetadata」;text/21-ch13-chapter-13-real-world-zig.txt:241,搜「Each field serves」)。 ↩ -
出处:同章第 258–295 段(
text/21-ch13-chapter-13-real-world-zig.txt:262,搜「realpathAlloc」;text/21-ch13-chapter-13-real-world-zig.txt:295,搜「setting up a safety net」)。 ↩ -
出处:同章第 297–312 段(
text/21-ch13-chapter-13-real-world-zig.txt:300,搜「pub fn deinit」;text/21-ch13-chapter-13-real-world-zig.txt:310,搜「simple value type」)。 ↩ -
出处:同章第 337–375 段(
text/21-ch13-chapter-13-real-world-zig.txt:343,搜「Sha256.init」;text/21-ch13-chapter-13-real-world-zig.txt:344,搜「4KB buffer」;text/21-ch13-chapter-13-real-world-zig.txt:374,搜「10GB video file」)。 ↩ -
出处:同章第 420–449 段(
text/21-ch13-chapter-13-real-world-zig.txt:422,搜「pub const FileIndex」;text/21-ch13-chapter-13-real-world-zig.txt:445,搜「path_storage might seem redundant」)。 ↩ -
出处:同章第 481–509 段(
text/21-ch13-chapter-13-real-world-zig.txt:483,搜「pub fn deinit」;text/21-ch13-chapter-13-real-world-zig.txt:507,搜「emptying the drawers」)。 ↩ -
出处:同章第 511–646 段(
text/21-ch13-chapter-13-real-world-zig.txt:513,搜「pub fn addFile」;text/21-ch13-chapter-13-real-world-zig.txt:567,搜「pub fn clone」)。 ↩ -
出处:同章第 680–838 段(
text/21-ch13-chapter-13-real-world-zig.txt:768,搜「pub fn traverseDirectory」;text/21-ch13-chapter-13-real-world-zig.txt:838,搜「stack overflow」)。 ↩ -
出处:同章第 719–748 段(
text/21-ch13-chapter-13-real-world-zig.txt:724,搜「fnmatch.h」;text/21-ch13-chapter-13-real-world-zig.txt:744,搜「battle-tested」)。 ↩ -
出处:同章第 749–764 段(
text/21-ch13-chapter-13-real-world-zig.txt:753,搜「Exclusion patterns take precedence」;text/21-ch13-chapter-13-real-world-zig.txt:764,搜「blacklist」)。 ↩ -
出处:同章第 941–995 段(
text/21-ch13-chapter-13-real-world-zig.txt:943,搜「pub const ChangeType」)。 ↩ -
出处:同章第 1023–1123 段(
text/21-ch13-chapter-13-real-world-zig.txt:1028,搜「pub fn detectChanges」;text/21-ch13-chapter-13-real-world-zig.txt:1049,搜「findByInode」;text/21-ch13-chapter-13-real-world-zig.txt:1121,搜「The magic here」)。 ↩ -
出处:同章第 1260–1337 段(
text/21-ch13-chapter-13-real-world-zig.txt:1262,搜「pub const CliOptions」;text/21-ch13-chapter-13-real-world-zig.txt:1290,搜「shorthands」;text/21-ch13-chapter-13-real-world-zig.txt:1320,搜「parseForCurrentProcess」)。 ↩ -
出处:同章第 1310–1350 段(
text/21-ch13-chapter-13-real-world-zig.txt:1315,搜「GeneralPurposeAllocator」;text/21-ch13-chapter-13-real-world-zig.txt:1334,搜「args.positionals」)。 ↩ -
出处:同章第 693–717、1001–1022 与 1421–1438 段(
text/21-ch13-chapter-13-real-world-zig.txt:696,搜「pub const TraversalConfig」;text/21-ch13-chapter-13-real-world-zig.txt:1003,搜「pub const DetectionConfig」;text/21-ch13-chapter-13-real-world-zig.txt:1422,搜「Create traversal configuration」)。 ↩ -
出处:同章第 1375–1616 段(
text/21-ch13-chapter-13-real-world-zig.txt:1475,搜「while (!should_exit)」;text/21-ch13-chapter-13-real-world-zig.txt:1484,搜「retry on next cycle」;text/21-ch13-chapter-13-real-world-zig.txt:1544,搜「new_baseline」)。 ↩ -
出处:同章第 1591–1617 段(
text/21-ch13-chapter-13-real-world-zig.txt:1593,搜「validatePath」;text/21-ch13-chapter-13-real-world-zig.txt:1597,搜「does not exist」)。 ↩ -
出处:同章第 1658–1714 段(
text/21-ch13-chapter-13-real-world-zig.txt:1681,搜「pub fn build(b: *std.Build)」;text/21-ch13-chapter-13-real-world-zig.txt:1694,搜「linkLibC」;text/21-ch13-chapter-13-real-world-zig.txt:1695,搜「addImport("args"」)。 ↩ -
出处:同章第 1716–1753 段(
text/21-ch13-chapter-13-real-world-zig.txt:1725,搜「ikskuh/zig-args」;text/21-ch13-chapter-13-real-world-zig.txt:1748,搜「Instead, we specify an exact」;text/21-ch13-chapter-13-real-world-zig.txt:1749,搜「worked once, it should work forever」)。 ↩ ↩2 -
出处:同章第 1635–1653 段(
text/21-ch13-chapter-13-real-world-zig.txt:1640,搜「Output Formats」)。 ↩ -
出处:同章第 1780–1795 段(
text/21-ch13-chapter-13-real-world-zig.txt:1784,搜「Database Backend」;text/21-ch13-chapter-13-real-world-zig.txt:1791,搜「Security Enhancements」)。 ↩ -
出处:同章第 1797–1846 段(
text/21-ch13-chapter-13-real-world-zig.txt:1806,搜「Command-Line Search Tool」;text/21-ch13-chapter-13-real-world-zig.txt:1836,搜「speed」)。 ↩ -
出处:同章第 1848–1867 段(
text/21-ch13-chapter-13-real-world-zig.txt:1856,搜「Zig Showtime」;text/21-ch13-chapter-13-real-world-zig.txt:1858,搜「Discord」)。 ↩ -
出处:同章第 1868–1887 段(
text/21-ch13-chapter-13-real-world-zig.txt:1876,搜「Core Language Development」)。 ↩ -
出处:同章第 1889–1908 段(
text/21-ch13-chapter-13-real-world-zig.txt:1896,搜「Self-Hosted compiler」;text/21-ch13-chapter-13-real-world-zig.txt:1904,搜「Async I/O」)。 ↩ -
出处:同章第 1910–1929 段(
text/21-ch13-chapter-13-real-world-zig.txt:1918,搜「Bun」;text/21-ch13-chapter-13-real-world-zig.txt:1922,搜「TigerBeetle」)。 ↩ ↩2 -
出处:同章第 1931–1949 段(
text/21-ch13-chapter-13-real-world-zig.txt:1946,搜「explicitness is a virtue」)。 ↩