跳转至

真实世界的 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 章的调试型分配器,泄漏会在退出时被它抓出来; 位置参数第一个是监控路径,缺省当前目录 .35。

配置在 CLI 和引擎之间还有一次翻译:runMonitor 把 CliOptions 拆成 两份引擎配置——TraversalConfig(max_depth、include/exclude、 hash_content、follow_symlinks)交给遍历器,DetectionConfig (monitor_timestamps/size/content/permissions、detect_moves)交给检测器。 引擎模块只认这两份结构、不知道命令行长什么样——这是原书模块分工里 config.zig 的存在理由:将来加 GUI 或配置文件,核心引擎一行不用动34。 主循环(单次或 --continuous 模式):每轮新建 current_index → 遍历 → detectChanges → 有变化就打印并克隆 current 为新基线; 遍历出错时连续模式「睡一觉下轮重试」,单次模式直接上报23。 validatePath 按错误类型给人类可读的报错(FileNotFound / AccessDenied), 而不是扔个裸错误24。

4.6 构建与依赖:第 11 章的复用照单

build.zig:createModule + addExecutable + exe.linkLibC() (fnmatch 需要)+ b.dependency("args", ...) + addImport25。 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)**——「能工作一次, 就该永远工作,没有神秘的『昨天还好好的』」26。

5. 专业扩展与项目方向(章末的「出去之后」)

原书给 FileGuard 列的生产级增强:机器可读输出(JSON/CSV)、写日志文件、 通知(邮件/Slack)、过滤掉 .DS_Store 之类的噪声、检出变更时跑钩子命令27。 另有一份架构级扩展清单,面向「从练手到生产」的跳跃:数据库后端 (存元数据与变更历史,做长期分析)、Web 仪表盘、插件系统(用户自定义 变更处理)、跨机分布式监控(集中上报)、安全增强(检出可疑变更)36。

十个练手项目方向(照原书清单,挑最常见的说):命令行搜索工具(grep 的更好用版)、 日志解析器、开发服务器 watcher、配置校验器、目录同步器、Markdown 转换器、 JSON/XML 处理器、文本处理瑞士刀、HTTP 客户端、构建产物清理器。 选择的共同理由:吃 Zig 的速度红利、依赖少、错误处理明确28。

社区资源(原书清单):Zig Showtime(Loris Cro 的视频系列)、Zig Discord (最活跃的枢纽)、Ziggit 论坛、GitHub 主仓、r/Zig29。 贡献路径:核心语言、文档、包、工具链、教育 advocacy30。

路线图(写作时):自举编译器(从 C++ 编译器迁到全 Zig 编写)、包管理器、 内存管理增强、互操作增强、性能优化、新 Async I/O、懂 comptime 的 语言服务器31。生产案例:Bun(JS 运行时)、TigerBeetle(分布式金融账务数据库)、 MachEngine(游戏引擎)、microzig(嵌入式)、各类 WASM 项目32。

判断(我们的,不是书里的): FileGuard 这一章是全书教学成色最高的一章—— 不是因为代码难,而是因为它诚实地展示了「工程权衡如何落到代码上」: 不用 inotify 是权衡(简单可调试 > 事件驱动的新鲜感); 内容哈希默认关是权衡(性能 > 彻底);path_storage 的冗余表是权衡 (一点内存 > 清理逻辑的脆弱)。每个权衡都在注释里留了「为什么」。 这正是第 1 章「透明」哲学的成熟形态:连决策过程都不藏。 如果错,会错在: 周期扫描在超高频变更场景(日志目录每秒上千次写) 会漏事件或性能劣化——原书没给这个边界;以及符号链接的重复计数问题被 一句「为简化接受」带过,真实使用要补 visited-inode 去重。

6. 作者的判断与证据

可核的: 全部代码结构、八模块分工(含 pattern.zig 与 config.zig)、双索引设计、构建文件与 zon 的锁哈希、 案例名单(Bun/TigerBeetle 等)2632。

立场: 「周期扫描优于平台事件 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。

  1. 工程权衡要写进注释:为什么不用 inotify、为什么哈希默认关、 为什么有 path_storage——FileGuard 每个「奇怪」设计都有明写的理由;
  2. 两阶段索引是监控类工具的通用骨架:基线 → 快照 → 比对 → 换基线;
  3. 双索引(路径 + inode) 让「移动」从「删除+创建」中分离出来—— inode 是文件系统的指纹;
  4. 第 9 章的纪律在实战里的样子:init 申请即 errdefer、deinit 先内容后容器、 深拷贝每条路径、哈希分块读;
  5. @cImport 是正经生产力:glob 匹配直接借 C 的 fnmatch,「不重复造轮子」;
  6. CLI 三件套:外部 args 库解析 + 合理默认值 + 按错误类型给可读报错;
  7. 依赖锁 commit 哈希换可复现性,代价是手动跟进安全更新;
  8. 连续模式的服务器素养:遍历失败「下轮重试」,不让临时故障杀掉监控;
  9. 章末地图:10 个练手项目、社区五站、路线图六项、生产案例五个(Bun、 TigerBeetle、MachEngine、microzig、WASM 项目);
  10. 全书落点:「explicitness is a virtue, performance is a priority, and each allocation has a home to return to」33。

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」)

  1. 出处:「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」)。 ↩

  2. 出处:同章第 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」)。 ↩

  3. 出处:同章第 110–123 段(text/21-ch13-chapter-13-real-world-zig.txt:112,搜「Detect multiple types」)。 ↩

  4. 出处:同章第 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」)。 ↩

  5. 出处:同章第 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」)。 ↩

  6. 出处:同章第 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」)。 ↩

  7. 出处:同章第 151–155 段(text/21-ch13-chapter-13-real-world-zig.txt:152,搜「moved, not deleted and recreated」)。 ↩

  8. 出处:同章第 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」)。 ↩

  9. 出处:同章第 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」)。 ↩

  10. 出处:同章第 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」)。 ↩

  11. 出处:同章第 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」)。 ↩

  12. 出处:同章第 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」)。 ↩

  13. 出处:同章第 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」)。 ↩

  14. 出处:同章第 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」)。 ↩

  15. 出处:同章第 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」)。 ↩

  16. 出处:同章第 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」)。 ↩

  17. 出处:同章第 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」)。 ↩

  18. 出处:同章第 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」)。 ↩

  19. 出处:同章第 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」)。 ↩

  20. 出处:同章第 941–995 段(text/21-ch13-chapter-13-real-world-zig.txt:943,搜「pub const ChangeType」)。 ↩

  21. 出处:同章第 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」)。 ↩

  22. 出处:同章第 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」)。 ↩

  23. 出处:同章第 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」)。 ↩

  24. 出处:同章第 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」)。 ↩

  25. 出处:同章第 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"」)。 ↩

  26. 出处:同章第 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」)。 ↩↩

  27. 出处:同章第 1635–1653 段(text/21-ch13-chapter-13-real-world-zig.txt:1640,搜「Output Formats」)。 ↩

  28. 出处:同章第 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」)。 ↩

  29. 出处:同章第 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」)。 ↩

  30. 出处:同章第 1868–1887 段(text/21-ch13-chapter-13-real-world-zig.txt:1876,搜「Core Language Development」)。 ↩

  31. 出处:同章第 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」)。 ↩

  32. 出处:同章第 1910–1929 段(text/21-ch13-chapter-13-real-world-zig.txt:1918,搜「Bun」;text/21-ch13-chapter-13-real-world-zig.txt:1922,搜「TigerBeetle」)。 ↩↩

  33. 出处:同章第 1931–1949 段(text/21-ch13-chapter-13-real-world-zig.txt:1946,搜「explicitness is a virtue」)。 ↩

  34. 出处:同章第 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」)。 ↩

  35. 出处:同章第 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」)。 ↩

  36. 出处:同章第 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」)。 ↩