<rss version="2.0">
  <channel>
    <title>Zig 语言中文社区</title>
    <link>https://ziglang.cc</link>
    <description>Zig 语言中文社区</description>
    <generator>Zine -- https://zine-ssg.io</generator>
    <language>en-US</language>
    <lastBuildDate>Fri, 06 Mar 2026 08:39:41 +0000</lastBuildDate>
    
      <item>
        <title>Zig 编译器内部架构与执行流程深度分析</title>
        <description>&lt;h2&gt;&lt;strong&gt;摘要&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;这篇文章的核心在于剖析 Zig 编译器独特的“懒惰编译”（Lazy Compilation）哲学、数据导向设计（Data-Oriented Design, DOD）在 AST/ZIR/AIR 阶段的具体应用，以及其如何通过统一的 InternPool 结构实现类型与值的同构存储。报告将详细阐述从源码解析到机器码生成的完整流水线，特别关注语义分析阶段（Sema）如何作为解释器与代码生成器的混合体，实现编译期代码执行（Comptime）与运行时指令发射的交织处理。此外，报告还将探讨 Zig 自举（Bootstrapping）过程的理论基础及其增量编译系统的实现原理。&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;1. 引言与设计哲学&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Zig 编译器不仅仅是一个将文本转换为二进制的转换器，它更像是一个针对源代码的查询引擎。与传统的 C/C++ 编译器通常采用的“以文件为单位的线性批处理”模式不同，Zig 编译器采用了一种基于依赖图的、按需驱动的架构。这种设计不仅是为了编译速度的优化，更是为了支撑 Zig 语言的核心特性——编译期代码执行（Comptime）与泛型元编程。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;1.1 懒惰编译（Lazy Compilation）的理论基础&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;在传统的编译模型中，包含一个头文件通常意味着该文件中的所有声明都会被解析和分析。然而，Zig 引入了极致的懒惰策略：只有当一个声明（函数、变量、结构体等）被程序入口点（如 main 函数或 test 块）直接或间接引用时，它才会被语义分析。&lt;/p&gt;&lt;p&gt;从理论上讲，这种机制使得 Zig 的泛型系统成为可能。在 Zig 中，泛型函数本质上是编译期执行的函数，其逻辑可能包含仅在特定类型参数下合法的分支。如果编译器采用“急切编译”（Eager Compilation），那么未被使用的、包含类型错误的分支将会导致编译失败。懒惰编译确保了只有实际实例化的代码路径才会受到类型检查系统的约束 1。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;1.2 数据导向架构（Data-Oriented Design）&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Zig 编译器的内部实现彻底摒弃了传统的面向对象编译器设计（即为每个 AST 节点分配一个独立的堆对象）。相反，它采用了数据导向设计（DOD）。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;结构数组（SoA）&lt;/strong&gt;：AST 节点、ZIR 指令、AIR 指令均存储在巨大的连续内存数组中（通常是 MultiArrayList）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;索引引用&lt;/strong&gt;：节点之间不通过 64 位的指针相互引用，而是通过 32 位的整数索引。这不仅减少了 50% 的指针内存开销，更重要的是极大地提高了 CPU 缓存（L1/L2 Cache）的命中率，因为遍历树结构变成了遍历连续的内存块 3。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;内存池化&lt;/strong&gt;：通过 ArenaAllocator 等机制，编译器在阶段结束时可以一次性释放整个阶段的内存，避免了数百万次微小对象析构带来的性能损耗。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;1.3 增量编译模型&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Zig 的增量编译并非通过对比文件时间戳实现，而是基于细粒度的依赖追踪。核心组件 Zcu (Zig Compilation Unit) 维护着一个全程序的依赖图。当源文件发生变更时，编译器仅重新分析受影响的声明及其传递依赖项，而非重新构建整个模块。这种设计要求中间表示（IR）必须高度可序列化且无上下文相关性，以便于缓存和重用。&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;2. 编译器执行流程总览&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Zig 的编译管线可以抽象为一系列数据变换阶段。每一个阶段都产生一种特定的中间表示（IR），其抽象程度逐级降低，类型信息逐级丰富。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;2.1 核心阶段图谱&lt;/strong&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;词法与语法分析 (Parse)&lt;/strong&gt;：源码 –&gt; 抽象语法树 (AST)。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;AST 降级 (AstGen)&lt;/strong&gt;：AST –&gt; Zig 中间表示 (ZIR)。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;语义分析 (Sema)&lt;/strong&gt;：ZIR –&gt; 分析后中间表示 (AIR) + 编译期常量 (Values)。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;代码生成 (CodeGen)&lt;/strong&gt;：AIR –&gt; 机器码 / LLVM IR / C 代码。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;链接 (Link)&lt;/strong&gt;：目标文件 –&gt; 可执行文件。&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;&lt;strong&gt;2.2 逻辑流程图 (Mermaid Representation)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;为了满足“流程图”的需求，以下是 Zig 编译器核心控制流的结构化描述：&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/zig-compiler.svg&quot;&gt;
&lt;figcaption&gt;How Zig compiler works&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;3. 第一阶段：解析与 AST 构建 (Parsing)&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;解析阶段是编译器与源代码的第一次接触。Zig 的解析器设计注重速度和错误恢复能力。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;3.1 标记化 (Tokenization)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;词法分析器（Tokenizer）扫描 UTF-8 编码的源文件字节流，生成标记（Token）流。Zig 语言的语法设计尽量减少了上下文敏感性，使得词法分析可以高效并行进行。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;SIMD 优化&lt;/strong&gt;：虽然具体实现随版本迭代，但其设计允许利用 SIMD 指令快速跳过空白符或识别标识符。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;零拷贝&lt;/strong&gt;：生成的 Token 并不拷贝字符串内容，而是存储指向源文件缓冲区的切片（Slice），即 start_index 和 length。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;3.2 抽象语法树 (AST) 的内存布局&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Zig 的 AST 不是一棵由对象指针连接的树，而是一组并行的数组（Struct of Arrays）。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;主节点数组&lt;/strong&gt;：存储 Tag（节点类型，如 fn_decl、var_decl）和主要数据（如标记索引）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;额外数据数组&lt;/strong&gt;：对于无法放入标准节点结构中的复杂节点（如包含多个参数的函数声明），主节点会存储一个索引，指向 extra_data 数组，那里存储了完整的子节点列表。 这种紧凑的布局使得整个 AST 可以完全驻留在 CPU 的 L2 或 L3 缓存中，大幅提升了后续遍历的速度。&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;strong&gt;4. 第二阶段：AST 降级与 ZIR 生成 (AstGen)&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;AstGen&lt;/strong&gt;（AST Generation）阶段负责将树状的 AST 转换为线性的指令序列——&lt;strong&gt;ZIR&lt;/strong&gt;（Zig Intermediate Representation）。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;4.1 ZIR 的核心特性：无类型 (Untyped)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;ZIR 最关键的特征是它是&lt;strong&gt;无类型&lt;/strong&gt;的 3。在这个阶段，编译器只关注语法结构，而不关心类型语义。例如，对于表达式 const x = a + b;，ZIR 会生成一条“加法”指令，引用 a 和 b，但此时编译器并不知道 a 和 b 是整数、浮点数还是向量，甚至不知道它们是否存在。&lt;/p&gt;&lt;p&gt;这种设计的必要性源于 Zig 的 comptime 特性。因为类型本身可以由函数在编译期返回（First-class Types），所以在执行 comptime 代码之前，AST 中很多节点的类型是不可知的。如果试图在 AstGen 阶段进行类型检查，就会陷入“为了知道类型需要执行代码，为了执行代码需要知道类型”的死锁。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;4.2 结果位置语义 (Result Location Semantics)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;在将递归的 AST 转换为线性的 ZIR 时，Zig 引入了 &lt;strong&gt;ResultLoc&lt;/strong&gt;（结果位置）的概念，以优化数据流向 6。当 AstGen 遍历一个 AST 节点时，它会向下传递一个 ResultLoc 参数，告诉子节点：“计算完结果后，请直接把数据写入这个位置。”&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;None/Discard&lt;/strong&gt;：父节点不需要这个值（例如 _ = foo();）。子节点生成计算指令，但不生成存储指令。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Return&lt;/strong&gt;：结果直接作为函数的返回值。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Instruction&lt;/strong&gt;：结果作为一个临时值，供后续指令引用。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Block&lt;/strong&gt;：结果应写入当前基本块的末尾。 这种机制有效地实现了“返回值优化”（RVO）的广义形式，避免了大量的临时变量拷贝，使得生成的 ZIR 极其精简。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;4.3 ZIR 指令集概览&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;ZIR 指令集比机器码高级，但比 AST 低级。常见指令包括：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;alloc&lt;/strong&gt;：在栈上分配空间（类型未知）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ret_node&lt;/strong&gt;：返回控制流。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;call&lt;/strong&gt;：调用函数（目标和参数均为索引引用）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;block / block_end&lt;/strong&gt;：定义词法作用域。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;extended&lt;/strong&gt;：用于处理极其复杂的结构，如包含大量字段的结构体初始化。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;由于 ZIR 不包含类型信息且不依赖外部文件，因此 ZIR 是&lt;strong&gt;文件级缓存&lt;/strong&gt;的理想对象。一旦源文件生成了 ZIR，只要文件内容不变，ZIR 就可以被持久化缓存并在下次编译时直接加载 4。&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;5. 第三阶段：统一存储 (The InternPool)&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;在深入语义分析之前，必须理解 Zig 编译器的“数据仓库”——&lt;strong&gt;InternPool&lt;/strong&gt;。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;5.1 类型即值 (Types as Values)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;在 Zig 语言理论中，类型（Type）只是值（Value）的一种特例。u32 是一个类型，同时它也是一个类型为 type 的值。为了在编译器内部统一处理这两者，Zig 使用 InternPool 存储所有的常量值和类型定义 3。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;去重（Interning）&lt;/strong&gt;：InternPool 保证了结构上的唯一性。如果在代码中两处定义了相同的结构体 struct { a: i32 }，或者两次计算出了整数 42，它们在 InternPool 中只会被存储一次，并拥有完全相同的索引（Index）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;轻量级比较&lt;/strong&gt;：判断两个类型是否相等，只需比较它们在 InternPool 中的索引是否相同（即 u32 比较）。这使得类型检查极度高效。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;5.2 值的表示&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;InternPool 中的值可以是简单的（如整数、布尔值），也可以是复杂的（如结构体实例、数组、函数体）。对于复杂值，索引指向池中的一段载荷（Payload）。这种集中式管理使得编译器在进行常量折叠（Constant Folding）时，可以直接操作池中的索引，而无需频繁分配内存。&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;6. 第四阶段：语义分析 (Sema) —— 编译器的核心&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;语义分析&lt;/strong&gt;（Semantic Analysis，简称 Sema）是 Zig 编译器最复杂、最核心的阶段。它不仅仅是类型检查器，本质上它是一个&lt;strong&gt;混合了解释执行功能的 ZIR 虚拟机&lt;/strong&gt; 7。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;6.1 Sema 作为 ZIR 解释器&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Sema 的工作方式是遍历 ZIR 指令流，并为每一条指令维护其状态。对于每条 ZIR 指令，Sema 执行以下逻辑循环：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;操作数解析&lt;/strong&gt;：查找该指令引用的操作数。这些操作数可能是之前指令产生的结果。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;类型推导与检查&lt;/strong&gt;：根据操作数的类型，验证当前操作的合法性。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;着色（Coloring）与分流&lt;/strong&gt;：&lt;ul&gt;&lt;li&gt;&lt;strong&gt;编译期路径 (Comptime)&lt;/strong&gt;：如果所有操作数都是编译期已知的常量（即它们在 inst_map 中对应的是 InternPool 的值），且操作本身支持编译期执行，Sema 会直接在其内部的虚拟机中计算结果。计算结果被存回 InternPool，并在 inst_map 中记录为“常量”。此过程不生成任何运行时代码。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;运行时路径 (Runtime)&lt;/strong&gt;：如果操作数包含运行时变量，或者操作具有副作用（如 I/O），Sema 会发射一条对应的 &lt;strong&gt;AIR 指令&lt;/strong&gt;。该指令的引用被记录在 inst_map 中。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;&lt;strong&gt;6.2 inst_map: 跨越时空的桥梁&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;inst_map 是 Sema 阶段的关键数据结构，它映射了 ZIR 指令索引 -&gt; 语义结果。&lt;/p&gt;&lt;p&gt;这个“语义结果”是一个联合体（Union），它可能是一个：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;常量值 (Value)&lt;/strong&gt;：指向 InternPool，表示该指令在编译期就被计算完成了。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;AIR 引用 (Air.Inst.Ref)&lt;/strong&gt;：指向生成的 AIR 代码缓冲区，表示该指令将在运行时执行。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;这种机制完美地解释了 Zig 如何在同一个语法结构中混合处理 comptime 和 runtime 代码。对于编译器来说，它们只是 inst_map 中不同的结果变体而已。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;6.3 懒惰依赖解析 (Lazy Dependency Resolution)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Sema 并不按顺序分析文件。它从根声明开始。当分析到一条引用其他函数（如 foo()）的指令时：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Sema 检查 foo 是否已经被分析。&lt;/li&gt;&lt;li&gt;如果没有，Sema &lt;strong&gt;挂起&lt;/strong&gt;当前函数的分析任务。&lt;/li&gt;&lt;li&gt;Sema 找到 foo 对应的 ZIR，并为 foo 启动一个新的 Sema 分析任务。&lt;/li&gt;&lt;li&gt;一旦 foo 分析完成（即推导出返回值类型），Sema &lt;strong&gt;恢复&lt;/strong&gt;之前的任务，继续往下执行。 这种递归的、按需的遍历确保了未被引用的代码永远不会被分析，从而避免了不必要的编译错误。&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;&lt;strong&gt;6.4 泛型单态化 (Monomorphization)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;当 Sema 遇到一个函数调用，且该函数带有 comptime 参数（例如 fn list(T: type) 中的 T）时，它会触发单态化机制。&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Sema 将传入的参数（如 u32）作为键。&lt;/li&gt;&lt;li&gt;Sema 检查该函数是否已经针对 u32 生成了实例。&lt;/li&gt;&lt;li&gt;如果没有，Sema 会克隆该函数的 ZIR，并将 T 绑定为 u32，然后对这个新的 ZIR 实例进行分析。&lt;/li&gt;&lt;li&gt;生成的 AIR 是专门针对 u32 优化的。&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;&lt;strong&gt;7. 第五阶段：分析后中间表示 (AIR)&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;AIR&lt;/strong&gt;（Analyzed Intermediate Representation）是 Sema 阶段的产出物。与 ZIR 不同，AIR 是&lt;strong&gt;全类型&lt;/strong&gt;（Fully Typed）且经过初步优化的 8。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;7.1 AIR 的结构特征&lt;/strong&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;全类型&lt;/strong&gt;：AIR 中的每一条指令都明确携带了类型信息。例如，ZIR 中的“加法”在 AIR 中会变体为 add_u32、add_f64 或 add_checked。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;显式控制流&lt;/strong&gt;：ZIR 中的高级控制流（如 defer、errdefer、try）在 AIR 中会被降级（Lowering）为更底层的形式。例如，defer 会被展开到所有的退出路径中。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;SSA 形式&lt;/strong&gt;：AIR 基本上遵循静态单赋值形式（SSA），这使得数据流分析更加容易。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;7.2 活跃度分析 (Liveness Analysis)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;在生成 AIR 后，编译器立即执行活跃度分析。这一步计算每个 AIR 指令生成的值的生命周期——它在何处诞生，在何处最后一次被使用（死亡）。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;墓碑机制 (Tombstones)&lt;/strong&gt;：分析结果会生成一张表，标记每个指令的“死亡点”。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;资源回收&lt;/strong&gt;：后端利用这些信息来重用寄存器或栈槽（Stack Slots）。如果一个值在第 10 行后不再使用，其占用的寄存器就可以在第 11 行分配给别的变量。这是 Zig 生成高效机器码的关键步骤之一 10。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;7.3 为什么需要两层 IR (ZIR vs AIR)？&lt;/strong&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;ZIR&lt;/strong&gt;：负责抽象语法，独立于类型系统，便于缓存及 IDE 工具分析。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;AIR&lt;/strong&gt;：负责抽象语义，包含精确的类型和执行逻辑，便于后端生成机器码。 这种分离使得编译器前端（AstGen）和中端（Sema）可以解耦，分别专注于语法正确性和语义正确性。&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;strong&gt;8. 第六阶段：代码生成 (CodeGen) 与后端&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Zig 支持多种后端，Sema 生成的 AIR 会被分发给选定的后端进行处理。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;8.1 语义与代码生成的交织 (Interleaving)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;为了降低内存峰值，Zig 编译器并不等待所有函数的 AIR 都生成完毕才开始代码生成。相反，一旦某个函数的 AIR 生成并经过活跃度分析，它就会立即被发送给 CodeGen 模块。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;即时释放&lt;/strong&gt;：一旦后端完成了该函数的机器码生成，对应的 AIR 数据结构就可以被释放（除非在增量编译模式下需要保留）。这使得编译器能够处理数百万行代码的巨型项目而不至于内存溢出。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;8.2 LLVM 后端&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;对于 ReleaseFast、ReleaseSafe 和 ReleaseSmall 构建模式，Zig 通常使用 LLVM 后端。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;转换&lt;/strong&gt;：AIR 指令被一对一或多对一地转换为 LLVM IR 指令。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;优化&lt;/strong&gt;：利用 LLVM 强大的优化管线（Pass Pipeline）进行循环展开、向量化、内联等高级优化。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;局限&lt;/strong&gt;：LLVM 庞大且慢，因此主要用于发布构建。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;8.3 自举后端 (Self-Hosted Backends)&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;对于 Debug 构建，Zig 优先使用自研的后端（如 x86_64, ARM64, WASM 后端）。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;直接生成&lt;/strong&gt;：这些后端直接将 AIR 转换为二进制机器码，跳过了生成 LLVM IR 的过程。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;速度优势&lt;/strong&gt;：由于省去了庞大的中间层，自举后端的编译速度通常比 LLVM 后端快数倍，极大地提升了开发时的“修改 - 编译 - 运行”循环效率 11。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;8.4 C 后端&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;Zig 能够将 AIR 转换为标准的 C 代码。这使得 Zig 可以“搭便车”运行在任何拥有 C 编译器的平台上（如一些嵌入式架构或特殊的超级计算机），实现了极致的可移植性。&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;9. 第七阶段：链接 (Linking)&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Zig 编译器内置了一个名为 zld（Zig Linker）的链接器，它直接集成在编译管线中。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;9.1 原地增量链接&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;对于 ELF (Linux) 和 Mach-O (macOS) 等格式，Zig 支持原地二进制修补。&lt;/p&gt;&lt;p&gt;当发生增量编译时，只有发生变化的函数会被重新生成机器码。zld 会计算新代码的大小：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;如果新代码小于等于旧代码占用的空间（加上填充区），直接覆盖旧代码。&lt;/li&gt;&lt;li&gt;如果新代码变大，链接器会将新代码追加到二进制文件的末尾，并修改所有调用该函数的跳转指令（Jumps/Calls）指向新地址。 这种技术使得 Zig 在大型项目中的重链接时间几乎可以忽略不计。&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;strong&gt;9.2 跨平台交叉编译&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;由于 Zig 自身携带了所有支持平台的 libc 定义和链接逻辑，它天生支持交叉编译。在架构上，这意味着 CodeGen 和 Link 阶段可以根据 Target Triple 动态加载不同的配置，而无需依赖宿主机的系统工具链。&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;10. 自举过程 (Bootstrapping) 理论&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Zig 是一种自举语言，即 Zig 编译器是用 Zig 编写的。为了从零构建编译器，Zig 采用了一个严格的四阶段自举链 13。&lt;/p&gt;&lt;h3&gt;&lt;strong&gt;10.1 阶段演进&lt;/strong&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Stage 1 (Resurrection)&lt;/strong&gt;：这是一个预编译的 WASM 二进制文件（或 C 源码），它包含了旧版本的 Zig 编译器逻辑。它不需要现存的 Zig 编译器，只需要一个 C 编译器或 WASM 解释器即可运行。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Stage 2 (Compiler Build)&lt;/strong&gt;：利用 Stage 1 编译器编译当前的 Zig 源码。生成的 zig2 可执行文件是一个功能完整的编译器，但由于 Stage 1 通常未进行激进优化，zig2 的运行速度较慢。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Stage 3 (Optimization)&lt;/strong&gt;：利用 zig2 再次编译 Zig 源码。因为 zig2 本身支持优化，生成的 zig3 是经过全优化的 Release 版本。这是最终发布给用户的版本。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Stage 4 (Verification)&lt;/strong&gt;：利用 zig3 再次编译源码。理论上，zig3 和 zig4 应该是二进制逐位一致的（Bit-identical），这用于验证编译器的确定性。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;这个过程确保了 Zig 不依赖于 C++ 代码库（移除了旧的 C++ 实现），实现了完全的语言自洽 15。&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;11. 总结&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Zig 编译器的内部架构展示了现代系统编程语言在编译原理上的突破。通过将&lt;strong&gt;懒惰语义分析&lt;/strong&gt;与&lt;strong&gt;数据导向的内存布局&lt;/strong&gt;相结合，Zig 成功地在一个统一的管线中解决了元编程的灵活性与编译速度之间的矛盾。&lt;/p&gt;&lt;p&gt;其核心流程可以概括为：&lt;strong&gt;解析&lt;/strong&gt;构建了高效的 AST 数组；&lt;strong&gt;AstGen&lt;/strong&gt; 将其转化为无类型的 ZIR 指令流并处理作用域；&lt;strong&gt;Sema&lt;/strong&gt; 作为解释器遍历 ZIR，通过 InternPool 统一管理类型与值，分离出编译期常量和运行时 AIR 指令；最后，&lt;strong&gt;CodeGen&lt;/strong&gt; 与 &lt;strong&gt;Link&lt;/strong&gt; 阶段通过增量技术将 AIR 转化为最终的高效机器码。&lt;/p&gt;&lt;p&gt;这种架构不仅使得 Zig 能够拥有媲美脚本语言的元编程能力，同时保持了系统级语言所需的裸机性能与确定性内存控制，为未来的编译器设计提供了一个极具参考价值的理论范本。&lt;/p&gt;&lt;h4&gt;&lt;strong&gt;Works cited&lt;/strong&gt;&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;How Zig incremental compilation is implemented internally? - Explain - Ziggit Dev, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/how-zig-incremental-compilation-is-implemented-internally/3543&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/how-zig-incremental-compilation-is-implemented-internally/3543&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Lazy Dependencies, Best Dependencies? - Brainstorming - Ziggit Dev, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/lazy-dependencies-best-dependencies/5509&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/lazy-dependencies-best-dependencies/5509&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Programming Language Compiler &amp; Toolchain | Augment Code, accessed January 24, 2026, &lt;a href=&quot;https://www.augmentcode.com/open-source/ziglang/zig&quot; target=&quot;_blank&quot;&gt;https://www.augmentcode.com/open-source/ziglang/zig&lt;/a&gt;&lt;/li&gt;&lt;li&gt;perform AstGen on whole files at once (AST-&gt;ZIR) · Issue #8516 · ziglang/zig - GitHub, accessed January 24, 2026, &lt;a href=&quot;https://github.com/ziglang/zig/issues/8516&quot; target=&quot;_blank&quot;&gt;https://github.com/ziglang/zig/issues/8516&lt;/a&gt;&lt;/li&gt;&lt;li&gt;How Zig incremental compilation is implemented internally? - #2 by mlugg - Explain - Ziggit, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/how-zig-incremental-compilation-is-implemented-internally/3543/2&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/how-zig-incremental-compilation-is-implemented-internally/3543/2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig AstGen: AST =&gt; ZIR - Mitchell Hashimoto, accessed January 24, 2026, &lt;a href=&quot;https://mitchellh.com/zig/astgen&quot; target=&quot;_blank&quot;&gt;https://mitchellh.com/zig/astgen&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Implementation of Comptime - Explain - Ziggit, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/implementation-of-comptime/5041&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/implementation-of-comptime/5041&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Sema: ZIR =&gt; AIR - Mitchell Hashimoto, accessed January 24, 2026, &lt;a href=&quot;https://mitchellh.com/zig/sema&quot; target=&quot;_blank&quot;&gt;https://mitchellh.com/zig/sema&lt;/a&gt;&lt;/li&gt;&lt;li&gt;zig/src/Air.zig at master · ziglang/zig - GitHub, accessed January 24, 2026, &lt;a href=&quot;https://github.com/ziglang/zig/blob/master/src/Air.zig&quot; target=&quot;_blank&quot;&gt;https://github.com/ziglang/zig/blob/master/src/Air.zig&lt;/a&gt;&lt;/li&gt;&lt;li&gt;sometimes there is an unwanted memcpy when passing large structs by-value · Issue #17580 · ziglang/zig - GitHub, accessed January 24, 2026, &lt;a href=&quot;https://github.com/ziglang/zig/issues/17580&quot; target=&quot;_blank&quot;&gt;https://github.com/ziglang/zig/issues/17580&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Stage 2 Proposal: Standardise a binary format for ZIR, and enable compilation to and from this representation · Issue #5635 · ziglang/zig - GitHub, accessed January 24, 2026, &lt;a href=&quot;https://github.com/ziglang/zig/issues/5635&quot; target=&quot;_blank&quot;&gt;https://github.com/ziglang/zig/issues/5635&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig builds are getting faster - Hacker News discussion thread, accessed January 24, 2026.&lt;/li&gt;&lt;li&gt;Building self-hosted from the original C++ implementation - Help - Ziggit, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/building-self-hosted-from-the-original-c-implementation/6607&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/building-self-hosted-from-the-original-c-implementation/6607&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Bootstrapping (compilers) - Wikipedia, accessed January 24, 2026, &lt;a href=&quot;https://en.wikipedia.org/wiki/Bootstrapping_(compilers)&quot; target=&quot;_blank&quot;&gt;https://en.wikipedia.org/wiki/Bootstrapping_(compilers)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Goodbye to the C++ Implementation of Zig - Zig Programming Language, accessed January 24, 2026, &lt;a href=&quot;https://ziglang.org/news/goodbye-cpp/&quot; target=&quot;_blank&quot;&gt;https://ziglang.org/news/goodbye-cpp/&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;</description>
        <link>https://ziglang.cc/post/2026-01-26-zig-compiler-deep-dive/</link>
        <pubDate>Mon, 26 Jan 2026 01:49:51 +0000</pubDate>
        <guid>https://ziglang.cc/post/2026-01-26-zig-compiler-deep-dive/</guid>
      </item>
    
      <item>
        <title>Zig 构建系统深度剖析：范式演进、实现机制与生态对比研究</title>
        <description>&lt;h2 id=&quot;introduction&quot;&gt;引言：系统编程构建工具的演进与危机&lt;/h2&gt;&lt;p&gt;在现代软件工程的广阔版图这一宏大叙事中，构建系统（Build Systems）始终扮演着基础设施的核心角色，却往往也是开发者体验中最薄弱的环节。对于系统级编程语言——尤其是 C 和 C++ 生态系统而言，构建过程的复杂性已成为阻碍生产力的主要瓶颈之一。几十年来，开发者们受困于一种二元分裂的开发模式：他们必须掌握目标语言（如 C++）来编写业务逻辑，同时还必须掌握一套完全不同的、往往晦涩难懂的构建描述语言（如 Make、CMake、Autotools 脚本）来管理编译过程。这种“语言与其构建工具的分离”不仅增加了认知负荷，导致了严重的“依赖地狱”问题，即为了构建一个项目，开发者往往需要预先安装编译器、构建生成器（如 CMake）、底层构建工具（如 Ninja 或 Make）以及各种脚本解释器（如 Python 或 Perl）。&lt;/p&gt;&lt;p&gt;Zig 语言的出现，标志着系统编程领域的一次重要范式转移。其构建系统（Zig Build System）并非仅仅是一个外挂的工具，而是语言工具链不可分割的有机组成部分 1。Zig 采用了一种激进的“零依赖”哲学，通过将构建逻辑直接通过 Zig 语言本身来表达，消除了对外部构建工具（如 Make、CMake）的依赖 3。这种设计不仅实现了构建脚本与源代码在语言层面的一致性，更通过其独特的“命令式定义，声明式执行”模型，重新定义了复杂系统软件的构建方式。&lt;/p&gt;&lt;p&gt;本报告旨在对 Zig 构建系统进行详尽的解构与分析。我们将深入探讨其背后的设计哲学，特别是为何在声明式配置大行其道的今天，Zig 依然选择了一种看似复古的命令式构建定义方式；我们将剖析其底层的有向无环图（DAG）实现机制、基于内容寻址的高级缓存架构以及独特的 LazyPath 抽象；最后，我们将把 Zig 置于更广阔的构建系统光谱中，与工业界标准的 CMake 以及现代化的 Cargo 进行深度对比，以评估其在不同应用场景下的优势与局限性。&lt;/p&gt;&lt;h2 id=&quot;paradigm-analysis&quot;&gt;范式解析：为何选择命令式而非声明式？&lt;/h2&gt;&lt;p&gt;在用户查询中，一个核心的疑问在于 Zig 为何采用命令式（Imperative）的编程方式来定义构建逻辑，而非像 Rust 的 Cargo 或 JavaScript 的 npm 那样采用声明式（Declarative）的配置文件（如 TOML 或 JSON）。要回答这一问题，必须深入理解系统编程的本质复杂性以及“图构建”与“图执行”之间的关键区别。&lt;/p&gt;&lt;h3 id=&quot;taxonomy-dilemma&quot;&gt;构建系统的分类学困境&lt;/h3&gt;&lt;p&gt;传统的构建系统大致可以分为两类。第一类是&lt;strong&gt;声明式系统&lt;/strong&gt;，如 Maven、Cargo 或 npm。在这类系统中，开发者在一个静态的数据文件（如 Cargo.toml）中列出项目的元数据、依赖项和构建目标。构建工具读取这些数据，并根据预设的逻辑执行构建。这种方式的优点是简洁、易读且易于被工具解析，但其缺点在于缺乏灵活性。当构建需求超出预设的配置选项时（例如，根据主机 CPU 是否支持 AVX512 指令集来动态调整编译参数，或者在构建过程中生成版本控制的头文件），声明式系统往往显得力不从心，迫使开发者编写额外的脚本（如 Rust 的 build.rs）来弥补功能的缺失 4。&lt;/p&gt;&lt;p&gt;第二类是&lt;strong&gt;命令式系统&lt;/strong&gt;，如 Make、Rake 或 Gradle（Groovy DSL）。在这类系统中，开发者编写的是脚本，明确指示构建工具“先做这一步，再做那一步”。这种方式提供了极大的灵活性，允许开发者使用循环、条件判断和函数抽象来处理复杂的构建逻辑。然而，传统的命令式脚本往往难以维护，且难以并行化，因为工具难以推断步骤之间的依赖关系。&lt;/p&gt;&lt;h3 id=&quot;hybrid-model&quot;&gt;Zig 的混合模型：命令式定义图，声明式执行图&lt;/h3&gt;&lt;p&gt;Zig 构建系统巧妙地融合了这两者的优势，采用了一种&lt;strong&gt;两阶段执行模型&lt;/strong&gt;。这种模型的核心在于区分“构建逻辑的定义阶段”和“构建任务的执行阶段”。&lt;/p&gt;&lt;p&gt;在 Zig 中，build.zig 文件本质上是一个标准的 Zig 源代码文件，它包含一个公开的 build 函数。当用户运行 zig build 命令时，系统首先编译并执行这个 build.zig 文件 6。在这个阶段，开发者可以使用完整的 Zig 语言特性——包括 if 条件判断、for 循环、自定义函数、文件 I/O 操作等——来描述构建过程。这就是所谓的&lt;strong&gt;命令式定义&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;然而，build 函数的执行并不会直接触发编译或链接操作。相反，build 函数中的 API 调用（如 b.addExecutable 或 b.addLibrary）实际上是在内存中构建一个&lt;strong&gt;构建图&lt;/strong&gt;（Build Graph），即一个有向无环图（DAG）7。例如，当代码中调用 const exe = b.addExecutable(…) 时，它仅仅是在图中创建了一个代表编译任务的节点（Step），而没有立即调用编译器。&lt;/p&gt;&lt;p&gt;当 build 函数执行完毕后，内存中就形成了一个完整的、静态的依赖关系图。随后的&lt;strong&gt;执行阶段&lt;/strong&gt;则完全是声明式的：构建运行器（Build Runner）遍历这个 DAG，根据依赖关系决定执行顺序，并利用并发机制并行执行那些互不依赖的步骤 8。&lt;/p&gt;&lt;h3 id=&quot;turing-complete-fallacy&quot;&gt;拒绝“图灵完备谬误”：系统级配置的必然选择&lt;/h3&gt;&lt;p&gt;关于构建配置是否应该图灵完备（Turing-complete）的争论在软件工程界由来已久。一种观点认为，配置应该是静态的、受限的，以防止构建脚本变得过于复杂和难以维护。然而，Zig 的设计者 Andrew Kelley 及其社区认为，对于系统级软件而言，构建过程本身就是一个复杂的程序 9。&lt;/p&gt;&lt;p&gt;在系统编程中，构建环境的差异性极大。一个项目可能需要同时支持 Windows、Linux、macOS 以及裸机嵌入式设备；可能需要根据编译器的版本开启或关闭特定的优化；可能需要在构建过程中动态生成代码（Code Generation）并将其作为输入传递给下一个编译步骤。静态的声明式配置（如 JSON 或 YAML）在面对这种动态需求时，往往需要引入复杂的模板语言或宏扩展，最终演变成一种笨拙且功能不全的脚本语言（即所谓的“格林斯潘第十定律”效应，CMake 的语法演变便是一个典型的例子）11。&lt;/p&gt;&lt;p&gt;Zig 通过直接使用通用编程语言（Zig）作为构建语言，避免了发明一套新的 DSL（领域特定语言）。开发者可以使用他们熟悉的 Zig 语法、标准库和调试工具来编写构建逻辑。这意味着，如果需要遍历一个目录下的所有 .zig 文件并将它们编译为独立的测试可执行文件，开发者只需写一个标准的 for 循环即可，而无需查阅 CMake 文档中关于 file(GLOB…) 和 foreach 的晦涩用法 3。&lt;/p&gt;&lt;p&gt;这种设计哲学的核心在于：&lt;strong&gt;复杂性是守恒的&lt;/strong&gt;。既然构建复杂的系统软件不可避免地需要逻辑判断和流程控制，那么与其在一个受限的声明式语言中痛苦地模拟这些逻辑，不如直接提供一个图灵完备的语言环境，让开发者能够以结构化、可维护的方式来管理这种复杂性 4。&lt;/p&gt;&lt;h2 id=&quot;internal-architecture&quot;&gt;内部架构与实现机制深度剖析&lt;/h2&gt;&lt;p&gt;Zig 构建系统的强大功能建立在一套精心设计的内部架构之上，涉及 std.Build API 的设计、构建图的节点抽象、缓存机制以及路径处理策略。&lt;/p&gt;&lt;h3 id=&quot;std-build&quot;&gt;std.Build 与构建图的构建&lt;/h3&gt;&lt;p&gt;Zig 构建系统的核心是标准库中的 std.Build 结构体（通常在构建脚本中简称为 b）。这个结构体充当了构建过程的上下文管理器，负责存储构建图的状态、解析命令行参数以及提供创建构建步骤的工厂方法 1。&lt;/p&gt;&lt;h4 id=&quot;step-interface&quot;&gt;Step 接口与多态性&lt;/h4&gt;&lt;p&gt;构建图的基本单元是 Step（步骤）。在 Zig 的标准库实现中，Step 是一个接口（通过结构体和函数指针实现），定义了所有构建任务必须遵守的契约。每一个具体的构建操作——无论是编译一个可执行文件（CompileStep）、运行一个命令（RunStep）、安装一个文件（InstallArtifactStep）还是生成文档——都是实现了 Step 接口的具体结构体 7。&lt;/p&gt;&lt;p&gt;Step 接口的核心包含两个主要部分：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;依赖管理&lt;/strong&gt;：每个 Step 都维护着一个依赖列表（dependencies: ArrayList(*Step)）。通过调用 stepA.dependOn(&amp;stepB)，开发者显式地在图中创建了一条边，表示 stepB 必须在 stepA 之前成功完成。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Make 函数&lt;/strong&gt;：这是执行实际构建逻辑的函数指针（makeFn）。当构建运行器决定执行某个步骤时，它会调用该步骤的 make 函数。&lt;/li&gt;&lt;/ol&gt;&lt;h4 id=&quot;top-level-steps&quot;&gt;顶层步骤与默认目标&lt;/h4&gt;&lt;p&gt;在 build.zig 中，并没有隐式的“默认”行为。如果开发者创建了一个编译步骤但没有将其连接到构建图的根部，那么这个步骤永远不会被执行。为了解决这个问题，std.Build 提供了几个预定义的顶层步骤，最常见的是 install 步骤。通过调用 b.installArtifact(exe)，开发者实际上是创建了一个安装步骤，并将其添加为默认 install 步骤的依赖，同时该安装步骤又依赖于编译步骤 1。当用户运行 zig build 时，系统默认查找并执行名为 install 的顶层步骤，从而触发整个依赖链的执行。&lt;/p&gt;&lt;h3 id=&quot;caching-system&quot;&gt;缓存系统：基于内容寻址的增量构建&lt;/h3&gt;&lt;p&gt;Zig 构建系统最引人注目的特性之一是其先进的缓存机制。与传统的 Make 工具依赖文件修改时间戳（Timestamp）来决定是否重新构建不同，Zig 采用了一套基于&lt;strong&gt;内容寻址存储&lt;/strong&gt;（Content-Addressable Storage, CAS）的哈希缓存系统 15。&lt;/p&gt;&lt;h4 id=&quot;hash-inputs&quot;&gt;哈希输入的全面性&lt;/h4&gt;&lt;p&gt;Zig 的缓存策略基于一种“偏执”的信任模型：哈希一切，不信任时间。为了决定一个构建步骤是否可以跳过，Zig 会计算一个综合哈希值，该哈希值不仅包含源文件的内容（SHA-256），还包含：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;编译器的版本（Zig 编译器的自举哈希）。&lt;/li&gt;&lt;li&gt;所有的编译参数和标志（Flags）。&lt;/li&gt;&lt;li&gt;目标架构（Target Architecture）、操作系统和 ABI。&lt;/li&gt;&lt;li&gt;所有依赖项的哈希值。&lt;/li&gt;&lt;li&gt;构建模式（Debug, ReleaseSafe 等）15。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;只有当所有这些输入的组合哈希值在缓存中存在且对应的输出工件（Artifact）完整时，Zig 才会跳过该步骤。这彻底解决了 C/C++ 开发中常见的“修改了头文件或编译选项但构建系统没有重新编译”的痛点，也避免了因系统时间偏差导致的构建错误。&lt;/p&gt;&lt;h4 id=&quot;cache-directory-structure&quot;&gt;缓存目录结构&lt;/h4&gt;&lt;p&gt;Zig 的缓存通常位于项目根目录下的 .zig-cache 或用户主目录下的全局缓存中。其内部结构经过精心设计以支持高效查找：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;o/ (Objects)&lt;/strong&gt;：存储实际的构建产物，如 .o 目标文件、可执行文件或静态库。这些文件以其内容的哈希值命名，确保即使不同项目生成了相同内容的中间文件，也可以共享缓存。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;h/ (Header Manifests)&lt;/strong&gt;：存储编译期间生成的头文件依赖清单。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;z/ (ZIR Code)&lt;/strong&gt;：存储 Zig 中间表示（Zig Intermediate Representation）的缓存数据，用于加速编译器的前端处理。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;tmp/&lt;/strong&gt;：临时目录。构建步骤首先将输出写入此目录，待验证无误后，通过原子重命名操作移动到 o/ 目录。这种机制保证了缓存的原子性和一致性，即使构建过程中途崩溃，也不会留下损坏的缓存文件 15。&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;lazypath&quot;&gt;LazyPath：构建时未知路径的抽象&lt;/h3&gt;&lt;p&gt;在 Zig 的“定义与执行分离”模型中，处理生成文件（Generated Files）是一个巨大的挑战。在 build.zig 运行的阶段（图构建阶段），编译尚未开始，因此编译器生成的输出文件实际上还不存在，自然也就没有具体的文件系统路径。为了解决这一时空悖论，Zig 引入了 LazyPath（惰性路径）的概念 17。&lt;/p&gt;&lt;p&gt;LazyPath 是一个代数数据类型（Union），它可以代表：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;一个已经存在的源文件路径（src_path）。&lt;/li&gt;&lt;li&gt;一个即将在未来由某个构建步骤生成的文件的引用（generated）。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;当开发者调用 run_step.addOutputFileArg(“generated.zig”) 时，该函数不会返回一个字符串，而是返回一个 LazyPath 对象。这个对象内部包含了一个指向生成它的 Step 的指针。随后，当这个 LazyPath 被传递给另一个步骤（例如 b.addExecutable）作为源码输入时，构建系统会自动识别出这种依赖关系，并在 DAG 中添加一条从生成步骤到消费步骤的边。&lt;/p&gt;&lt;p&gt;直到构建图开始执行，且生成步骤成功完成后，LazyPath 才会解析为实际的文件系统绝对路径。这种机制使得 Zig 能够优雅地处理复杂的代码生成流水线（如使用 Protobuf 编译器生成 Zig 代码，然后立即编译该代码），而无需用户手动管理复杂的路径依赖 1。&lt;/p&gt;&lt;h2 id=&quot;key-features&quot;&gt;关键特性与差异化优势&lt;/h2&gt;&lt;p&gt;Zig 构建系统不仅在架构上独树一帜，更在功能特性上提供了一系列针对系统编程痛点的解决方案，使其在功能上超越了传统的构建工具。&lt;/p&gt;&lt;h3 id=&quot;cross-compilation&quot;&gt;交叉编译的一等公民地位&lt;/h3&gt;&lt;p&gt;在 GCC 或 Clang 的传统工作流中，交叉编译（例如在 Linux x86_64 主机上编译 Windows ARM64 程序）是一项令人望而生畏的任务。开发者通常需要下载并配置专门的交叉编译工具链，设置复杂的 sysroot，并确保链接正确的 libc 版本。&lt;/p&gt;&lt;p&gt;Zig 构建系统将交叉编译视为默认的标准功能。std.Build 提供了 standardTargetOptions 辅助函数，允许用户通过简单的命令行参数（如 -Dtarget=aarch64-linux-musl）来切换构建目标 1。&lt;/p&gt;&lt;p&gt;其背后的实现机制在于 Zig 编译器捆绑了主流 libc 实现（如 glibc, musl, mingw-w64）的源代码以及 macOS 的 SDK 存根。当请求交叉编译时，Zig 不会依赖主机系统的库，而是根据目标架构动态编译所需的 libc 组件，并将其缓存起来。这使得开发者可以在任何安装了 Zig 的机器上，为任何 Zig 支持的平台生成二进制文件，而无需安装任何额外的外部工具链 19。&lt;/p&gt;&lt;h3 id=&quot;zig-cc&quot;&gt;zig cc：乃至 C/C++ 项目的构建利器&lt;/h3&gt;&lt;p&gt;Zig 构建系统并不仅限于构建 Zig 代码。通过 zig cc 和 zig c++ 命令，Zig 暴露了其内部集成的 Clang 编译器前端。这使得 Zig 可以作为一个功能完备的 C/C++ 编译器使用，并且直接继承了 Zig 的交叉编译能力和缓存机制。&lt;/p&gt;&lt;p&gt;在 build.zig 中，开发者可以使用 exe.addCSourceFile 无缝地混合编译 C 源文件和 Zig 源文件。构建系统会自动处理头文件路径、宏定义以及链接过程。这一特性非常强大，以至于包括 Rust（通过 cargo-zigbuild）和 Go 在内的其他语言社区，也开始使用 zig cc 作为其交叉编译 C 依赖库的首选方案 21。对于 C/C++ 项目而言，这意味着可以用一个几十行代码的 build.zig 替换掉成百上千行的 CMake 脚本，同时获得开箱即用的交叉编译支持。&lt;/p&gt;&lt;h3 id=&quot;code-generation&quot;&gt;代码生成与元编程的深度集成&lt;/h3&gt;&lt;p&gt;在系统编程中，构建期间运行工具以生成源代码（Meta-programming）是常见需求。Zig 构建系统通过 addRunArtifact API 将这一过程标准化。开发者可以在同一个 build.zig 中定义一个用于代码生成的 Zig 可执行文件，将其编译为宿主机的原生代码，运行它生成 .zig 或 .c 文件，然后将这些生成的文件作为源文件添加到主程序的编译步骤中 1。&lt;/p&gt;&lt;p&gt;由于所有这些步骤都在同一个构建图中管理，Zig 能够精确地追踪生成工具的源码变化。如果生成工具的代码被修改，构建系统会自动重新编译工具，重新运行生成步骤，并重新编译主程序，整个过程无需人工干预。这种级别的集成在 Make 或 CMake 中通常需要复杂的自定义命令和文件依赖声明才能实现。&lt;/p&gt;&lt;h3 id=&quot;package-manager&quot;&gt;包管理器的去中心化设计&lt;/h3&gt;&lt;p&gt;从 Zig 0.11 版本开始，构建系统集成了包管理功能。与 npm 或 Cargo 依赖中心化注册表不同，Zig 采用了去中心化的设计。依赖项在 build.zig.zon 文件中通过 URL（通常是 GitHub 发布的 tarball 链接）和内容哈希（Multihash）来定义 24。&lt;/p&gt;&lt;p&gt;Zig 的包管理器不仅下载 Zig 源码，还能处理 C/C++ 依赖。由于 Zig 构建系统可以构建 C/C++ 代码，一个依赖包可以包含 C 源码和一个 build.zig 文件。当主项目依赖该包时，Zig 会自动下载源码并根据当前的构建目标（Target）从源码编译该库。这彻底解决了 C/C++ 生态中长期存在的二进制分发兼容性问题——所有依赖都从源码编译，确保了 ABI 的一致性 26。&lt;/p&gt;&lt;h2 id=&quot;ecosystem-comparison&quot;&gt;生态对比：Zig vs. CMake vs. Cargo&lt;/h2&gt;&lt;p&gt;为了更清晰地定位 Zig 构建系统，我们将其与工业界标准的 CMake 和现代化的 Cargo 进行详细对比。&lt;/p&gt;&lt;h3 id=&quot;zig-vs-cmake&quot;&gt;Zig vs. CMake&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;CMake&lt;/strong&gt; 是目前 C/C++ 世界的事实标准。它本质上是一个构建系统生成器，读取 CMakeLists.txt 并生成 Makefile 或 Ninja 文件。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;语言与语法&lt;/strong&gt;：CMake 使用一种自创的脚本语言，语法历史包袱沉重，基于字符串处理（Stringly Typed），对列表和空格的处理常常让开发者感到困惑（如 “Santa barfed on a Christmas tree” 的形容）12。相比之下，Zig 使用强类型的通用编程语言，拥有编译器检查、语法高亮和代码补全，逻辑表达清晰且不易出错。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;跨平台能力&lt;/strong&gt;：CMake 的跨平台依赖于寻找系统中已安装的编译器和库，这导致在不同环境下的构建结果往往不一致（“Works on my machine” 问题）。Zig 通过捆绑编译器和 libc，实现了真正的“一次编写，到处编译”，不依赖系统环境 19。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;生态惯性&lt;/strong&gt;：CMake 的最大优势在于生态。几乎所有现存的 C/C++ 库都提供 CMake 支持。虽然 Zig 可以构建 C 代码，但要移植一个复杂的 CMake 项目到 build.zig 仍然需要手动重写构建逻辑，这是一笔不小的迁移成本 27。&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;zig-vs-cargo&quot;&gt;Zig vs. Cargo (Rust)&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Cargo&lt;/strong&gt; 被广泛认为是现代包管理器的标杆，它使用声明式的 Cargo.toml 和约定优于配置的原则，提供了极佳的开箱体验。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;配置范式&lt;/strong&gt;：Cargo 是纯声明式的，这使得简单项目极其容易上手。然而，一旦涉及复杂的构建逻辑（如链接 C 库、生成代码），Cargo 必须退回到 build.rs 脚本。build.rs 虽然也是 Rust 代码，但它与 Cargo 的声明式模型是割裂的，且对交叉编译的支持（尤其是涉及 C 依赖时）往往需要复杂的 hack 28。Zig 从一开始就承认构建的复杂性，因此 build.zig 统一了配置和逻辑，处理复杂场景更加自然。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;C/C++ 互操作性&lt;/strong&gt;：Cargo 将 C/C++ 视为二等公民，需要依赖 cc crate 和外部编译器。Zig 将 C/C++ 视为一等公民，原生支持混合编译。对于纯 Rust 项目，Cargo 体验更佳；但对于混合了大量 C 代码的系统级项目，Zig 的构建系统展现出了更强的控制力和一致性 21。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;稳定性&lt;/strong&gt;：Cargo 已经非常成熟稳定。Zig 仍处于 1.0 之前的快速迭代期，API 经常发生破坏性变更（Breaking Changes），这对于追求长期稳定的商业项目来说是一个显著的风险 30。&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;limitations-and-future&quot;&gt;局限性与未来展望&lt;/h2&gt;&lt;p&gt;尽管 Zig 构建系统展现了巨大的潜力，但它目前并非完美无缺，仍面临着成长的阵痛。&lt;/p&gt;&lt;h3 id=&quot;api-stability&quot;&gt;API 稳定性与学习曲线&lt;/h3&gt;&lt;p&gt;由于 Zig 尚未发布 1.0 版本，std.Build API 仍在频繁变动。例如，从 0.11 到 0.12 版本，依赖处理和路径处理的 API 发生了重大重构，导致旧的教程和代码片段迅速失效 30。这种不稳定性增加了学习成本，开发者往往需要通过阅读标准库源码而非文档来解决问题。此外，从声明式思维转向命令式定义图的思维模式，对于习惯了 npm 或 Cargo 的开发者来说也是一个不小的门槛 33。&lt;/p&gt;&lt;h3 id=&quot;visualization-tools&quot;&gt;可视化与调试工具的缺失&lt;/h3&gt;&lt;p&gt;虽然构建逻辑构建了一个清晰的 DAG，但目前 Zig 缺乏标准化的工具来可视化这个图。当构建过程出现循环依赖或意外的执行顺序时，开发者很难直观地看到图的全貌。社区已有相关的探索（如生成 Graphviz 文件），但尚未集成到官方工具链中 35。&lt;/p&gt;&lt;h3 id=&quot;security-and-sandboxing&quot;&gt;安全性与沙盒化&lt;/h3&gt;&lt;p&gt;由于 build.zig 是图灵完备的且在构建主机上执行，理论上恶意的构建脚本可以执行任何操作（如删除用户文件、上传隐私数据）。这是一个安全性隐患。Zig 团队的未来规划包括将构建脚本编译为 WebAssembly（WASM），并在受限的沙盒环境中执行，从而在保留灵活性的同时确保构建过程的安全性 32。&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot;&gt;结论&lt;/h2&gt;&lt;p&gt;Zig 构建系统代表了软件构建领域的一次深刻反思与重构。它通过打破构建脚本与程序代码的界限，利用通用编程语言的表达力来驾驭系统构建的固有复杂性。其“命令式定义，声明式执行”的范式，结合底层的图驱动架构和内容寻址缓存，为系统级软件开发提供了一种兼具灵活性、性能与正确性的解决方案。&lt;/p&gt;&lt;p&gt;特别是对于那些深受 C/C++ 构建工具碎片化之苦，或需要进行复杂交叉编译的项目而言，Zig 提供了一种极具吸引力的替代方案——它不仅是一个构建工具，更是一个能将 C、C++ 和 Zig 统一在同一套可复现、零依赖工作流中的元构建系统。尽管目前仍受限于 API 的稳定性和文档的完善度，但其设计理念无疑指明了下一代系统编程工具链的发展方向：集成化、可编程化与去中心化。&lt;/p&gt;&lt;table&gt;&lt;tr&gt;&lt;th align=&apos;left&apos;&gt;特性维度&lt;/th&gt;&lt;th align=&apos;left&apos;&gt;Zig 构建系统 (std.Build)&lt;/th&gt;&lt;th align=&apos;left&apos;&gt;CMake&lt;/th&gt;&lt;th align=&apos;left&apos;&gt;Cargo (Rust)&lt;/th&gt;&lt;th align=&apos;left&apos;&gt;Make&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&apos;left&apos;&gt;&lt;strong&gt;配置范式&lt;/strong&gt;&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;命令式定义 -&gt; 声明式 DAG&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;混合脚本语言&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;声明式 TOML (+ build.rs)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;命令式 (Shell 命令)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&apos;left&apos;&gt;&lt;strong&gt;配置语言&lt;/strong&gt;&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;Zig (通用、强类型)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;CMake DSL (字符串脚本)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;TOML (静态数据)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;Makefile 语法&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&apos;left&apos;&gt;&lt;strong&gt;交叉编译&lt;/strong&gt;&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;极佳 (原生支持，自带 libc)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;困难 (需手动配置工具链)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;良好 (需外部工具辅助)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;困难 (完全手动)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&apos;left&apos;&gt;&lt;strong&gt;C/C++ 支持&lt;/strong&gt;&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;原生一等公民 (zig cc)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;原生一等公民&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;二等公民 (需 cc crate)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;原生 (调用编译器)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&apos;left&apos;&gt;&lt;strong&gt;依赖管理&lt;/strong&gt;&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;去中心化 (.zon + git)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;碎片化 (FetchContent, Vcpkg)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;中心化 (crates.io)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;无 (依赖系统包)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&apos;left&apos;&gt;&lt;strong&gt;缓存机制&lt;/strong&gt;&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;内容寻址哈希 (CAS)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;主要是时间戳&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;内容寻址哈希&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;时间戳&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&apos;left&apos;&gt;&lt;strong&gt;外部依赖&lt;/strong&gt;&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;零 (自包含工具链)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;需安装编译器 + 构建工具&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;需 Rust 工具链&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;需 Shell 环境&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&apos;left&apos;&gt;&lt;strong&gt;学习曲线&lt;/strong&gt;&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;高 (API 复杂且变动)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;高 (语法晦涩)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;低 (简单项目) / 中 (复杂项目)&lt;/td&gt;&lt;td align=&apos;left&apos;&gt;中&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;hr&gt;&lt;h2 id=&quot;references&quot;&gt;参考&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;Zig Build System - Zig Programming Language, accessed January 24, 2026, &lt;a href=&quot;https://ziglang.org/learn/build-system/&quot; target=&quot;_blank&quot;&gt;https://ziglang.org/learn/build-system/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Introduction to Zig - 9 Build System, accessed January 24, 2026, &lt;a href=&quot;https://pedropark99.github.io/zig-book/Chapters/07-build-system.html&quot; target=&quot;_blank&quot;&gt;https://pedropark99.github.io/zig-book/Chapters/07-build-system.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Understanding `build.zig`: A Practical Introduction to Zig’s Build System - DEV Community, accessed January 24, 2026, &lt;a href=&quot;https://dev.to/hexshift/understanding-buildzig-a-practical-introduction-to-zigs-build-system-6gh&quot; target=&quot;_blank&quot;&gt;https://dev.to/hexshift/understanding-buildzig-a-practical-introduction-to-zigs-build-system-6gh&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Declarative vs Imperative - a Thoughtful Comparison - DEV Community, accessed January 24, 2026, &lt;a href=&quot;https://dev.to/marzelin/declarative-vs-imperative-a-thoughtful-comparison-4hm6&quot; target=&quot;_blank&quot;&gt;https://dev.to/marzelin/declarative-vs-imperative-a-thoughtful-comparison-4hm6&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Build System plans for future? - Reddit, accessed January 24, 2026, &lt;a href=&quot;https://www.reddit.com/r/Zig/comments/1cwpoaq/zig_build_system_plans_for_future/&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/Zig/comments/1cwpoaq/zig_build_system_plans_for_future/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Build System Internals – Mitchell Hashimoto, accessed January 24, 2026, &lt;a href=&quot;https://mitchellh.com/zig/build-internals&quot; target=&quot;_blank&quot;&gt;https://mitchellh.com/zig/build-internals&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Build System | Jiacai Liu’s personal website, accessed January 24, 2026, &lt;a href=&quot;https://en.liujiacai.net/2023/04/13/zig-build-system/&quot; target=&quot;_blank&quot;&gt;https://en.liujiacai.net/2023/04/13/zig-build-system/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Build - zig.guide, accessed January 24, 2026, &lt;a href=&quot;https://zig.guide/build-system/zig-build/&quot; target=&quot;_blank&quot;&gt;https://zig.guide/build-system/zig-build/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig is a modern imperative programming language with ADTs: &lt;a href=&quot;https://ziglang.org/d&quot; target=&quot;_blank&quot;&gt;https://ziglang.org/d&lt;/a&gt;… | Hacker News, accessed January 24, 2026, &lt;a href=&quot;https://news.ycombinator.com/item?id=40307807&quot; target=&quot;_blank&quot;&gt;https://news.ycombinator.com/item?id=40307807&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Introduction to the Zig Programming Language - Andrew Kelley, accessed January 24, 2026, &lt;a href=&quot;https://andrewkelley.me/post/intro-to-zig.html&quot; target=&quot;_blank&quot;&gt;https://andrewkelley.me/post/intro-to-zig.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;While I agree with most of what you wrote, CMake feels supercharged compared to, accessed January 24, 2026, &lt;a href=&quot;https://news.ycombinator.com/item?id=26940772&quot; target=&quot;_blank&quot;&gt;https://news.ycombinator.com/item?id=26940772&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig build system as an alternative to CMake? : r/embedded - Reddit, accessed January 24, 2026, &lt;a href=&quot;https://www.reddit.com/r/embedded/comments/1i9nyj4/zig_build_system_as_an_alternative_to_cmake/&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/embedded/comments/1i9nyj4/zig_build_system_as_an_alternative_to_cmake/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Language Oriented Zig? - Brainstorming - Ziggit Dev, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/language-oriented-zig/11584&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/language-oriented-zig/11584&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Build - Gamedev Guide, accessed January 24, 2026, &lt;a href=&quot;https://ikrima.dev/dev-notes/zig/zig-build/&quot; target=&quot;_blank&quot;&gt;https://ikrima.dev/dev-notes/zig/zig-build/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The Zig’s Build Cache - by Alex Rios - Medium, accessed January 24, 2026, &lt;a href=&quot;https://medium.com/@alex.rios/the-zigs-build-cache-eae263d1fad4&quot; target=&quot;_blank&quot;&gt;https://medium.com/@alex.rios/the-zigs-build-cache-eae263d1fad4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Big picture of the Zig caching system. - GitHub Gist, accessed January 24, 2026, &lt;a href=&quot;https://gist.github.com/matu3ba/92e5df1166c51b3725dbd04f7ff1cb4e&quot; target=&quot;_blank&quot;&gt;https://gist.github.com/matu3ba/92e5df1166c51b3725dbd04f7ff1cb4e&lt;/a&gt;&lt;/li&gt;&lt;li&gt;A Clean Build of OpenSSL using Zig - dzfrias, accessed January 24, 2026, &lt;a href=&quot;https://dzfrias.dev/blog/openssl-zig/&quot; target=&quot;_blank&quot;&gt;https://dzfrias.dev/blog/openssl-zig/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Ok, this should be an easy one y’all… : r/Zig - Reddit, accessed January 24, 2026, &lt;a href=&quot;https://www.reddit.com/r/Zig/comments/1fdzq2t/ok_this_should_be_an_easy_one_yall/&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/Zig/comments/1fdzq2t/ok_this_should_be_an_easy_one_yall/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;`zig cc`: a Powerful Drop-In Replacement for GCC/Clang - Andrew Kelley, accessed January 24, 2026, &lt;a href=&quot;https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html&quot; target=&quot;_blank&quot;&gt;https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;zig cc for OSX: sysroot usage · Issue #15098 · ziglang/zig - GitHub, accessed January 24, 2026, &lt;a href=&quot;https://github.com/ziglang/zig/issues/15098&quot; target=&quot;_blank&quot;&gt;https://github.com/ziglang/zig/issues/15098&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Learning Zig and Zig Build by porting Piper’s CMakeLists.txt - Compile and Run, accessed January 24, 2026, &lt;a href=&quot;https://compileandrun.com/zig-build-cargo-piper/&quot; target=&quot;_blank&quot;&gt;https://compileandrun.com/zig-build-cargo-piper/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Bundle zig-cc in rustup by default - Rust Internals, accessed January 24, 2026, &lt;a href=&quot;https://internals.rust-lang.org/t/bundle-zig-cc-in-rustup-by-default/22096&quot; target=&quot;_blank&quot;&gt;https://internals.rust-lang.org/t/bundle-zig-cc-in-rustup-by-default/22096&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig C/C++ Compiler — WTF is Zig C++ | by Ed Yu | Medium, accessed January 24, 2026, &lt;a href=&quot;https://medium.com/@edlyuu/zig-c-c-compiler-wtf-is-zig-c-790d9ad8d85b&quot; target=&quot;_blank&quot;&gt;https://medium.com/@edlyuu/zig-c-c-compiler-wtf-is-zig-c-790d9ad8d85b&lt;/a&gt;&lt;/li&gt;&lt;li&gt;How to build and use Zig packages | Matthew Freire, accessed January 24, 2026, &lt;a href=&quot;https://mattfreire.blog/posts/how-to-build-and-use-zig-packages&quot; target=&quot;_blank&quot;&gt;https://mattfreire.blog/posts/how-to-build-and-use-zig-packages&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Package Manager — WTF is Zon - Medium, accessed January 24, 2026, &lt;a href=&quot;https://medium.com/@edlyuu/zig-package-manager-wtf-is-zon-df5ecbafcc54&quot; target=&quot;_blank&quot;&gt;https://medium.com/@edlyuu/zig-package-manager-wtf-is-zon-df5ecbafcc54&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Package Manager 2 — WTF is Build.Zig.Zon and Build.Zig (0.11.0 Update) - Medium, accessed January 24, 2026, &lt;a href=&quot;https://medium.com/@edlyuu/zig-package-manager-2-wtf-is-build-zig-zon-and-build-zig-0-11-0-update-5bc46e830fc1&quot; target=&quot;_blank&quot;&gt;https://medium.com/@edlyuu/zig-package-manager-2-wtf-is-build-zig-zon-and-build-zig-0-11-0-update-5bc46e830fc1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig comptime for C projects using CMake - Showcase - Ziggit, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/zig-comptime-for-c-projects-using-cmake/11629&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/zig-comptime-for-c-projects-using-cmake/11629&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Anyone using the Zig Build system with Rust? Was it worth it. Resources for zig build system and rust code for OSDev? - Reddit, accessed January 24, 2026, &lt;a href=&quot;https://www.reddit.com/r/osdev/comments/1fzrvrq/anyone_using_the_zig_build_system_with_rust_was/&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/osdev/comments/1fzrvrq/anyone_using_the_zig_build_system_with_rust_was/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;build system tradeoffs - the website of jyn, accessed January 24, 2026, &lt;a href=&quot;https://jyn.dev/build-system-tradeoffs&quot; target=&quot;_blank&quot;&gt;https://jyn.dev/build-system-tradeoffs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig breaking change – Initial Writergate | Hacker News, accessed January 24, 2026, &lt;a href=&quot;https://news.ycombinator.com/item?id=44461067&quot; target=&quot;_blank&quot;&gt;https://news.ycombinator.com/item?id=44461067&lt;/a&gt;&lt;/li&gt;&lt;li&gt;What are the breaking changes of 0.14 : r/Zig - Reddit, accessed January 24, 2026, &lt;a href=&quot;https://www.reddit.com/r/Zig/comments/1jb26pq/what_are_the_breaking_changes_of_014/&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/Zig/comments/1jb26pq/what_are_the_breaking_changes_of_014/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig tips: v0.11 std.build API / package manager changes | Hexops’ devlog, accessed January 24, 2026, &lt;a href=&quot;https://devlog.hexops.com/2023/zig-0-11-breaking-build-changes/&quot; target=&quot;_blank&quot;&gt;https://devlog.hexops.com/2023/zig-0-11-breaking-build-changes/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig build system is really difficult to grasp.. - Reddit, accessed January 24, 2026, &lt;a href=&quot;https://www.reddit.com/r/Zig/comments/1jfiwm9/zig_build_system_is_really_difficult_to_grasp/&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/Zig/comments/1jfiwm9/zig_build_system_is_really_difficult_to_grasp/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;I started learning Zig … - Reddit, accessed January 24, 2026, &lt;a href=&quot;https://www.reddit.com/r/Zig/comments/1p0ur0d/i_started_learning_zig/&quot; target=&quot;_blank&quot;&gt;https://www.reddit.com/r/Zig/comments/1p0ur0d/i_started_learning_zig/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Visual Build Graph - Brainstorming - Ziggit, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/visual-build-graph/9096&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/visual-build-graph/9096&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Zig Build System Basics - Media - Ziggit Dev, accessed January 24, 2026, &lt;a href=&quot;https://ziggit.dev/t/zig-build-system-basics/10275&quot; target=&quot;_blank&quot;&gt;https://ziggit.dev/t/zig-build-system-basics/10275&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;</description>
        <link>https://ziglang.cc/post/2026-01-25-zig-build-deep-dive/</link>
        <pubDate>Sun, 25 Jan 2026 07:26:13 +0000</pubDate>
        <guid>https://ziglang.cc/post/2026-01-25-zig-build-deep-dive/</guid>
      </item>
    
      <item>
        <title>在 0.15.2 版本使用 C ABI 模拟 Zig ABI</title>
        <description>&lt;p&gt;白糖：艾达，我怎么才能把我的 zig 项目发布出去，但是不公开源码呀？&lt;/p&gt;&lt;p&gt;艾达：可以分发二进制库文件和相关符号定义文件（符合 C ABI 的符号定义），照着这样写就行了。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// lib.zig&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Container&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;c_int&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// project.zig&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Container&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;c_int&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;白糖：导出为 C 库呀。但是你这就一个结构，一个函数，这么写当然没什么问题，如果有很多函数，结构呢？&lt;/p&gt;&lt;p&gt;艾达：别忘了 zig 的&lt;code&gt;comptime&lt;/code&gt;机制呀，编译时可以自动导出符号并且生成符号定义文件。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// lib.zig&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Container&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;c_int&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Container&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;string constant variable_builtin type variable_member variable&quot;&gt;&amp;quot;struct&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;decls&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decl&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;field&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decl&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;field_type&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;field_type_info&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_type_info&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;string constant variable_builtin type variable&quot;&gt;&amp;quot;fn&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;function_builtin&quot;&gt;@export&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decl&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;艾达：如果结构内还有类型定义，可以递归调用，这样就只需要传最外层的类型。怕参数错误，可以在导出前做各种检测来避免。注意这个方法需要函数标记&lt;code&gt;pub&lt;/code&gt;以及不需要标记&lt;code&gt;export&lt;/code&gt;。对于&lt;code&gt;extern union&lt;/code&gt;和&lt;code&gt;enum(c_int)&lt;/code&gt;也是相似的。&lt;/p&gt;&lt;p&gt;白糖：这里只有导出，那符号定义文件怎么自动生成。而且编译时必须是常量，如果可以把调用了&lt;code&gt;exports&lt;/code&gt;的类型都收集起来给运行时用就好了。艾达，有什么办法吗？&lt;/p&gt;&lt;p&gt;艾达：编译时收集有些困难。不过办法还是有的，如果&lt;code&gt;exports&lt;/code&gt;在编译时和生成符号定义文件时是不同的函数是不是就可以解决了。接下来就是 zig 构建系统的事情，我们要利用其 module 机制。&lt;/p&gt;&lt;p&gt;艾达：首先我们把项目分成多个模块，分别是库本身、导出符号模块、生成符号定义文件模块和依赖生成文件模块的库本身以及运行生成符号定义文件的模块。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// lib.zig&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;export_mod&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;export_mod&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExportedContainer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;c_int&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;export_mod&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;export_mode&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;exportAllSymbol&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;exportAllSymbol&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;export_mod&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;exportsymbols&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExportedContainer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// export_symbol.zig&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;export_mode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;exportsymbols&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;

    &lt;span class=&quot;function_builtin&quot;&gt;@export&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// gen_header.zig&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;export_mode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;exportsymbols&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;genHeader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Target&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// gen_header_main.zig&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;lib&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;lib&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;exportAllSymbol&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;艾达：最后在 build.zig 中创建依赖。&lt;/p&gt;&lt;pre class=&quot;mermaid&quot;&gt;
graph TD
    lib_builder --&gt; lib
    lib -- 依赖 --- symbol_mod

    gen_header --&gt; gen_main
    gen_main -- 依赖 --- gen_header_lib[lib: gen_header_lib]
    gen_header_lib[lib: gen_header_lib] -- 依赖 --- gen_mod
&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// build.zig&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 构建库以及导出符号&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;symbol_mod&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;export_symbol.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lib&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;lib.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;imports&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;export_mod&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;symbol_mod&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lib_builder&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;lib&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_module&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lib_builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 生成符号定义文件&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gen_mod&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;gen_header.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gen_header_lib&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;lib.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;imports&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;export_mod&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;//注意名字需要相同&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gen_mod&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gen_main&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;gen_header_main.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;imports&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;lib&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 与 gen_header_main 中对应&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gen_header_lib&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;gen_main&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_module&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gen_main&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;艾达：现在完成了构建库时自动生成相关符号定义文件，实现了分享 zig 库不公开源码的功能。因为用 C ABI 所以会有一些限制，例如 zig 标准库的一些类型不能导出，需要实现 C 版本的。&lt;/p&gt;&lt;p&gt;艾达：具体生成的函数这里省略了，就是递归类型的&lt;code&gt;decls&lt;/code&gt;和&lt;code&gt;fields&lt;/code&gt;字段根据类型输出相应文本。不过 zig 的&lt;code&gt;Type&lt;/code&gt;有些限制，生成会有些不完美，比如函数信息就没有参数名，&lt;code&gt;struct&lt;/code&gt;内的&lt;code&gt;union&lt;/code&gt;字段不知道初始化的哪个变体等。&lt;/p&gt;&lt;p&gt;白糖：太好了，有什么例子可以看看吗？&lt;/p&gt;&lt;p&gt;艾达：当然！&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// lib&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@Vector&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// symbol.zig 符号定义文件&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Color&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;g&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main_Color_init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@Vector&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;callconv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;艾达：对了，如果不想在构建库的同时生成符号定义文件可以修改 build.zig。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// b.getInstallStep().dependOn(&amp;amp;run.step);&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;gen_main&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;generate the header.&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;艾达：在命令行运行&lt;code&gt;zig build gen_main&lt;/code&gt;就可以单独生成了。&lt;/p&gt;&lt;p&gt;白糖：太好了，爱你！艾达。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2026-01-18-shipping-zig-libraries-with-c-abi/</link>
        <pubDate>Sun, 18 Jan 2026 13:05:00 +0000</pubDate>
        <guid>https://ziglang.cc/post/2026-01-18-shipping-zig-libraries-with-c-abi/</guid>
      </item>
    
      <item>
        <title>显式之美：从 `std.fs.cwd()` 看 Zig 的工程哲学</title>
        <description>&lt;p&gt;在许多主流编程语言（如 C, Python, Go）中，访问文件通常是一个极其简单的动作：&lt;code&gt;open(&amp;quot;file.txt&amp;quot;)&lt;/code&gt;。但在 Zig 中，你通常必须先通过 &lt;code&gt;std.fs.cwd()&lt;/code&gt; 获取当前工作目录的句柄，再通过该句柄去打开文件。&lt;/p&gt;&lt;p&gt;这种设计初看起来增加了代码的“摩擦力”，但深究其背后，你会发现它精准地践行了 Zig 的核心设计理念：&lt;strong&gt;显式、安全、不隐藏任何复杂性&lt;/strong&gt;。&lt;/p&gt;&lt;h2 id=&quot;capability-based-security&quot;&gt;1. 显式权力：能力导向安全 (Capability-based Security)&lt;/h2&gt;&lt;p&gt;Zig 奉行&lt;strong&gt;最小权限原则&lt;/strong&gt;。在传统语言中，任何一段代码（甚至是第三方库）只要能调用全局的 &lt;code&gt;open()&lt;/code&gt;，就意味着它拥有了访问整个文件系统的潜在权力。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Zig 的做法：&lt;/strong&gt; 文件系统被抽象为 &lt;code&gt;Dir&lt;/code&gt; 对象（目录句柄）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;工程优势：&lt;/strong&gt; 如果你编写一个处理图像的库函数，你可以要求调用者传入一个 &lt;code&gt;Dir&lt;/code&gt; 句柄。这意味着你的库函数&lt;strong&gt;只能&lt;/strong&gt;看到并操作这个目录下的文件，它无法越权去读取用户的敏感文件（如 &lt;code&gt;~/.ssh/id_rsa&lt;/code&gt;）。&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;no-implicit-global-state&quot;&gt;2. 拒绝隐式全局状态：线程安全与确定性&lt;/h2&gt;&lt;p&gt;在 POSIX 标准中，当前工作目录（CWD）是一个&lt;strong&gt;进程级&lt;/strong&gt;的全局状态。在多线程环境下，这会引发严重的隐患。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;隐式风险：&lt;/strong&gt; 如果线程 A 调用了 &lt;code&gt;chdir()&lt;/code&gt; 更改了工作目录，线程 B 正在进行的相对路径操作会瞬间指向错误的位置。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Zig 的解决方案：&lt;/strong&gt; &lt;code&gt;std.fs.cwd()&lt;/code&gt; 返回的是一个指向当前目录的静态句柄。Zig 鼓励开发者在程序启动初期获取句柄，然后将其显式传递。即使进程的全局 CWD 发生变化，你持有的 &lt;code&gt;Dir&lt;/code&gt; 句柄依然锁定在它原本指向的物理位置。&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;cross-platform-consistency&quot;&gt;3. 跨平台的真实抽象 (Cross-platform Consistency)&lt;/h2&gt;&lt;p&gt;不同操作系统的路径逻辑差异巨大：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Windows:&lt;/strong&gt; 依赖驱动器号（&lt;code&gt;C:\&lt;/code&gt;）和反斜杠。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Linux/Unix:&lt;/strong&gt; 统一的根目录（&lt;code&gt;/&lt;/code&gt;）和正斜杠。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;WASI (WebAssembly):&lt;/strong&gt; 甚至没有根目录的概念，只有宿主环境预先“挂载”给模块的目录句柄。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;通过强制从一个 &lt;code&gt;Dir&lt;/code&gt; 句柄（如 &lt;code&gt;cwd()&lt;/code&gt;）开始操作，Zig 抹平了这些差异。无论是在开发桌面应用还是编译为 WASI 模块，代码逻辑都是统一的：&lt;strong&gt;起点句柄 + 相对路径&lt;/strong&gt;。&lt;/p&gt;&lt;h2 id=&quot;path-traversal-defense&quot;&gt;4. 路径穿越攻击的天然防线&lt;/h2&gt;&lt;p&gt;路径穿越（Path Traversal）是常见的文件系统漏洞，攻击者通过 &lt;code&gt;../&lt;/code&gt; 尝试跳出预设目录。&lt;/p&gt;&lt;p&gt;Zig 的 &lt;code&gt;Dir&lt;/code&gt; 结构体方法（如 &lt;code&gt;dir.openFile(...)&lt;/code&gt;）在设计上就偏向于在当前句柄的范围内进行解析。这种基于句柄的操作方式，比直接拼接不可信的字符串路径要安全得多，因为它从逻辑层面界定了操作的边界。&lt;/p&gt;&lt;h2 id=&quot;resource-lifecycle-management&quot;&gt;5. 资源生命周期的显式管理&lt;/h2&gt;&lt;p&gt;在 Zig 中，&lt;code&gt;Dir&lt;/code&gt; 往往需要显式关闭。这符合 Zig &lt;strong&gt;“没有隐藏控制流、没有隐藏资源分配”&lt;/strong&gt; 的理念。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 1. 显式获取当前起点&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cwd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 2. 明确基于起点创建目录&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;makePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;output/logs&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 3. 打开子目录句柄，生命周期清晰&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;log_dir&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;openDir&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;output/logs&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;log_dir&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;log_dir&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;trace.txt&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;summary&quot;&gt;总结：为什么要多写一行代码？&lt;/h2&gt;&lt;p&gt;Zig 认为，&lt;strong&gt;为了方便而隐藏复杂性，最终会导致维护的灾难。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;要求你先写 &lt;code&gt;cwd()&lt;/code&gt; 的本质，是强制让你意识到：&lt;strong&gt;文件系统操作不是在真空中进行的，它始终依赖于上下文、权限和环境。&lt;/strong&gt; 这种“摩擦力”在编写简单的单文件脚本时可能是负担，但在构建高性能、高可靠性的系统软件时，它是防止逻辑崩塌的最坚实保障。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2026-01-13-why-zig-uses-cwd/</link>
        <pubDate>Tue, 13 Jan 2026 07:54:31 +0000</pubDate>
        <guid>https://ziglang.cc/post/2026-01-13-why-zig-uses-cwd/</guid>
      </item>
    
      <item>
        <title>Zig 0.15 中的新 Writer 接口</title>
        <description>&lt;blockquote&gt;&lt;p&gt;原文：&lt;a href=&quot;https://www.openmymind.net/Zigs-New-Writer/&quot; target=&quot;_blank&quot;&gt;https://www.openmymind.net/Zigs-New-Writer/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;正如你可能听说过的，Zig 的&lt;code&gt;Io&lt;/code&gt;命名空间正在重新设计。最终，这将意味着重新引入异步。作为第一步，Writer 和 Reader 接口以及一些相关代码已经过改进。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;这篇文章是根据 Zig 的 2025 年 7 月中旬开发版本撰写的。它不适用于 Zig 0.14.x(或任何以前的版本),并且可能随着更多 Io 命名空间的返工而过时。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;不久前，我写了一篇博客文章，&lt;a href=&quot;https://www.openmymind.net/In-Zig-Whats-a-Writer/&quot; target=&quot;_blank&quot;&gt;Zig’s Writers&lt;/a&gt;试图解释 Zig 的 Writer。充其量，我会将当前状态描述为“混淆”两个 Writer 界面，同时经常处理&lt;code&gt;anytype&lt;/code&gt;. .和虽然&lt;code&gt;anytype&lt;/code&gt;很方便，它缺乏开发人员人体工程学。此外，目前的设计对于一些常见情况存在重大性能问题。&lt;/p&gt;&lt;p&gt;新&lt;code&gt;Writer&lt;/code&gt;接口是&lt;code&gt;std.Io.Writer&lt;/code&gt;. .至少，实现必须提供&lt;code&gt;drain&lt;/code&gt;功能。其签名看起来像：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;drain&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;splat&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你可能会惊讶于这是自定义编写者需要实现的方法。它不仅需要一个字符串数组，但那是什么&lt;code&gt;splat&lt;/code&gt;参数？像我一样，你可能期望一个更简单的&lt;code&gt;write&lt;/code&gt;方法：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;事实证明&lt;code&gt;std.Io.Writer&lt;/code&gt;有内置的缓冲。例如，如果我们想要一个&lt;code&gt;Writer&lt;/code&gt;为 A&lt;code&gt;std.fs.File&lt;/code&gt;我们需要提供缓冲：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当然，如果我们不想要缓冲，我们总能传递一个空的缓冲区：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就解释了为什么自定义编写者需要实现一个&lt;code&gt;drain&lt;/code&gt;方法，而不是更简单的东西，如&lt;code&gt;write&lt;/code&gt;. .&lt;/p&gt;&lt;p&gt;最简单的实现方法&lt;code&gt;drain&lt;/code&gt;,在进行这次更大的大修时，Zig 标准库已经升级了很多，是：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;drain&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;io_w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;splat&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;splat&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@fieldParentPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;interface&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io_w&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;WriteFailed&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们忽略了&lt;code&gt;splat&lt;/code&gt;参数，只需在中写第一个值&lt;code&gt;data&lt;/code&gt;(&lt;code&gt;data.len &amp;gt; 0&lt;/code&gt;保证是真实的)。这 转&lt;code&gt;drain&lt;/code&gt;进入什么更简单&lt;code&gt;write&lt;/code&gt;方法会看起来像。因为我们返回写入的字节长度，&lt;code&gt;std.Io.Writer&lt;/code&gt;会知道我们可能没有写所有数据并调用&lt;code&gt;drain&lt;/code&gt;再次，如果有必要，与其余的数据。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;如果你被调用混淆了&lt;code&gt;@fieldParentPtr&lt;/code&gt;&lt;a href=&quot;https://www.openmymind.net/Zigs-New-LinkedList-API/&quot; target=&quot;_blank&quot;&gt;upcoming linked list changes&lt;/a&gt;查看我关于即将到来的链接列表更改的帖子。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;实际执行&lt;code&gt;drain&lt;/code&gt;为&lt;code&gt;File&lt;/code&gt;是一个非平凡的〜150 行代码。它具有特定于平台的代码，&lt;a href=&quot;https://www.openmymind.net/TCP-Server-In-Zig-Part-3-Minimizing-Writes-and-Reads/#writev&quot; target=&quot;_blank&quot;&gt;并在可能的情况下利用矢量 I/O。&lt;/a&gt;显然，提供简单的实现或更优化的实现具有灵活性。&lt;/p&gt;&lt;p&gt;就像当前状态，当你做&lt;code&gt;file.writer(&amp;amp;buffer)&lt;/code&gt;你没有得到一个&lt;code&gt;std.Io.Writer&lt;/code&gt;. .相反，你得到一个&lt;code&gt;File.Writer&lt;/code&gt;. .获取实际&lt;code&gt;std.Io.Writer&lt;/code&gt;,你需要访问&lt;code&gt;interface&lt;/code&gt;领域。这只是一个惯例，但期望它在整个标准和第三方图书馆中使用。准备好看很多&lt;code&gt;&amp;amp;xyz.interface&lt;/code&gt;打电话！&lt;/p&gt;&lt;p&gt;这种简化&lt;code&gt;File&lt;/code&gt;显示三种类型之间的关系：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;buffer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtable&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drain&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drain&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// this has a bunch of other fields&lt;/span&gt;
        
        &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;drain&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;io_w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;splat&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@fieldParentPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;interface&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io_w&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ....&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实例&lt;code&gt;File.Writer&lt;/code&gt;需要存在于某个地方 (例如在堆栈上),因为那是&lt;code&gt;std.Io.Writer&lt;/code&gt;接口存在。有可能 那个&lt;code&gt;File&lt;/code&gt;可以直接有一个&lt;code&gt;writer_interface: std.Io.Writer&lt;/code&gt;字段，但这会限制你每个文件一个写入器，并且会膨胀&lt;code&gt;File&lt;/code&gt;结构。&lt;/p&gt;&lt;p&gt;我们可以从上面看到，当我们调用&lt;code&gt;Writer&lt;/code&gt;一个“界面”,它只是一个正常的结构。它有几个领域超越&lt;code&gt;buffer&lt;/code&gt;和&lt;code&gt;vtable.drain&lt;/code&gt;,但这些是唯一两个具有非默认值;我们必须提供它们。因&lt;code&gt;Writer&lt;/code&gt;接口实现了很多典型的“Writer”行为，比如&lt;code&gt;writeAll&lt;/code&gt;和&lt;code&gt;print&lt;/code&gt;(用于格式化写作)。它还有多种方法，只有&lt;code&gt;Writer&lt;/code&gt;实施可能会关心。例如，&lt;code&gt;File.Writer.drain&lt;/code&gt;必须调用&lt;code&gt;consume&lt;/code&gt;以便作者的内部状态可以更新。在文档中并排列出所有这些功能，起初让我感到困惑。希望这是文档生成有朝一日能够帮助解开的东西。&lt;/p&gt;&lt;p&gt;新&lt;code&gt;Writer&lt;/code&gt;已经接管了多种方法。例如，&lt;code&gt;std.fmt.formatIntBuf&lt;/code&gt;已经不存在了。替代者是&lt;code&gt;printInt&lt;/code&gt;方法&lt;code&gt;Writer&lt;/code&gt;. .但这需要一个&lt;code&gt;Writer&lt;/code&gt;实例而不是简单&lt;code&gt;[]u8&lt;/code&gt;以前要求。&lt;/p&gt;&lt;p&gt;很容易错过，但&lt;code&gt;Writer.fixed([]u8) Writer&lt;/code&gt;函数是你正在寻找的。您将将此用于迁移到的任何函数&lt;code&gt;Writer&lt;/code&gt;用来在 A 上工作&lt;code&gt;buffer: []u8&lt;/code&gt;. .&lt;/p&gt;&lt;p&gt;迁移时，_可能会遇到以下错误：在“…”中没有名为“adaptToNewApi”的字段或成员函数。_你可以看到为什么发生这种情况，通过查看更新的实现&lt;code&gt;std.fmt.format&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;adapter&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;adaptToNewApi&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;new_interface&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;WriteFailed&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为这个功能被移动到&lt;code&gt;std.Io.Writer&lt;/code&gt;, 任何&lt;code&gt;writer&lt;/code&gt;传入&lt;code&gt;format&lt;/code&gt;必须能够升级到新接口。这是完成的，同样，只是惯例，通过让“老”Writer 揭露一个&lt;code&gt;adaptToNewApi&lt;/code&gt;返回一个类型的方法，它暴露了一个&lt;code&gt;new_interface: std.Io.Writer&lt;/code&gt;领域。这是很容易实现使用基本&lt;code&gt;drain&lt;/code&gt;实现，你可以在标准库中找到一些例子，但如果你不控制传统作者，那就没什么帮助了。&lt;/p&gt;&lt;p&gt;我犹豫是否要对这一变化发表意见。我不懂语言设计。然而，虽然我认为这是对当前 API 的改进，但我一直认为直接添加缓冲到&lt;code&gt;Writer&lt;/code&gt;不是理想的。&lt;/p&gt;&lt;p&gt;我认为大多数语言都通过作文处理缓冲。你把一个 Reader / Writer ,并把它包装在缓冲阅读器或缓冲器。这种方法似乎既简单易懂，又易于实施，同时具有强大功能。它可以应用于缓冲和 IO 之外的东西。Zig 似乎在与这种模式作斗争。而不是为此类问题提供一种有凝聚力和通用的方法，而是将一个特定 API(IO) 的特定特征 (缓冲) 融入到标准库中。也许我太密集了，无法理解，或者未来的变化会更全面地解决这个问题。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2025-09-18-new-writer/</link>
        <pubDate>Thu, 18 Sep 2025 00:58:33 +0000</pubDate>
        <guid>https://ziglang.cc/post/2025-09-18-new-writer/</guid>
      </item>
    
      <item>
        <title>Zig 新 Writer 接口的内部实现</title>
        <description>&lt;blockquote&gt;&lt;p&gt;原文：&lt;a href=&quot;https://joegm.github.io/blog/inside-zigs-new-writer-interface/&quot; target=&quot;_blank&quot;&gt;https://joegm.github.io/blog/inside-zigs-new-writer-interface/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Zig 版本 0.15.1 最近发布，带来了一些破坏性的标准库更改，这些更改在 Zig 社区引起了轩然大波。&lt;/p&gt;&lt;p&gt;这一事件被 Zig 社区称为 “Writergate”，因为它围绕着标准库的 Reader 和 Writer 接口的破坏性大改而展开。新版本非常复杂，声称在各个方面都有改进，尤其是在性能和对优化器的友好性方面。&lt;/p&gt;&lt;p&gt;我将尽力具体解释新的 Writer 接口，深入了解其工作原理以及它比其他接口实现更好的地方。&lt;/p&gt;&lt;p&gt;但首先，让我们回顾一下在 “Writergate” 时代之前，Writer 接口在 Zig 中是如何使用的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三个 Writer 的故事&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在 0.15.1 之前，接受 Writer 作为函数参数主要有 3 种方式，它们都有各自的优点，但没有一个是完美的。如果你不感兴趣，可以直接跳到我介绍新 Writer 的部分。&lt;/p&gt;&lt;p&gt;本节是在 Zig 0.14.1 的背景下编写的，不适用于更新的版本。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;GenericWriter&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Generic Writer，位于 &lt;code&gt;std.io.GenericWriter&lt;/code&gt;，通常被别名为 &lt;code&gt;std.io.Writer&lt;/code&gt;，顾名思义，它是一个泛型类型。它需要 3 个编译时参数来创建一个新类型：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;Context&lt;/code&gt; 类型，用作 &lt;code&gt;write&lt;/code&gt; 函数的第一个参数。&lt;/li&gt;&lt;li&gt;&lt;code&gt;Error&lt;/code&gt; 类型，包含所有可能由写入操作引起的错误。&lt;/li&gt;&lt;li&gt;一个 &lt;code&gt;write&lt;/code&gt; 函数，它接受一个 &lt;code&gt;Context&lt;/code&gt; 以及一些要写入的字节，并返回一个 &lt;code&gt;Error&lt;/code&gt; 或者写入的字节数。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;让我们看看 &lt;code&gt;std.fs.File&lt;/code&gt; 是如何实现它的：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// std.fs.File&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;/// 操作系统特定的文件描述符或文件句柄。&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;WriteError&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;posix&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;WriteError&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;WriteError&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_windows&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;windows&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;WriteFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;posix&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;WriteError&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// GenericWriter!&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;File&lt;/code&gt; 有一个字段，即它的句柄。它有一个 &lt;code&gt;write&lt;/code&gt; 函数，它接受一个 &lt;code&gt;File&lt;/code&gt; 并可以返回一个 &lt;code&gt;WriteError&lt;/code&gt;。这就是创建泛型 Writer 所需的全部内容，使用 &lt;code&gt;io.Writer(File, WriteError, write)&lt;/code&gt; 和一个方便的函数将 &lt;code&gt;File&lt;/code&gt; 转换为 &lt;code&gt;File.Writer&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;以下是如何使用此 API：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getStdOut&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Hello, GenericWriter!&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;GenericWriter&lt;/code&gt; 使用核心 &lt;code&gt;write&lt;/code&gt; 函数来提供其他方便的写入函数，例如 &lt;code&gt;writeAll&lt;/code&gt;、&lt;code&gt;print&lt;/code&gt;、&lt;code&gt;writeStruct&lt;/code&gt; 等。任何想要写入文件的函数都可以将 &lt;code&gt;File.Writer&lt;/code&gt; 作为参数，就可以正常工作。&lt;/p&gt;&lt;p&gt;但是，问题在于：&lt;code&gt;GenericWriter&lt;/code&gt; 本身不是一个接口。接受 &lt;code&gt;File.Writer&lt;/code&gt; 的函数不能传递 &lt;code&gt;std.net.Stream.Writer&lt;/code&gt;，因为即使这两种类型都是使用 &lt;code&gt;GenericWriter&lt;/code&gt; 创建的，它们也不是同一种类型。缺少的是一种调度机制。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;调度的必要性&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;GenericWriter&lt;/code&gt; 缺少的是一种将单个接口分派到许多不同的可能的 Writer 实现的方法。调度技术分为两类：动态调度，在运行时执行；静态调度，由编译器在编译时执行。&lt;/p&gt;&lt;p&gt;让我们首先检查旧的动态调度的 Writer 接口，称为 &lt;code&gt;AnyWriter&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;AnyWriter&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;std.io.AnyWriter&lt;/code&gt; 是 0.14.1 中的动态调度 Writer。与 &lt;code&gt;GenericWriter&lt;/code&gt; 的主要区别在于 &lt;code&gt;AnyWriter&lt;/code&gt; 不是泛型的。它是一个单一的、具体的类型，使用它的函数可以与它的任何实现一起使用。&lt;/p&gt;&lt;p&gt;&lt;code&gt;AnyWriter&lt;/code&gt; 有两个字段：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;context&lt;/code&gt;: &lt;code&gt;*const anyopaque&lt;/code&gt;,&lt;/li&gt;&lt;li&gt;&lt;code&gt;writeFn&lt;/code&gt;: &lt;code&gt;*const fn (context: *const anyopaque, bytes: []const u8) anyerror!usize&lt;/code&gt;,&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code&gt;context&lt;/code&gt; 是一个类型擦除的指针，指向实现执行写入操作所需的任何数据。&lt;code&gt;writeFn&lt;/code&gt; 指向一个函数，该函数使用此上下文数据执行写入操作，并且可以返回 &lt;code&gt;anyerror&lt;/code&gt;，字面意思是任何可能的错误值。&lt;/p&gt;&lt;p&gt;&lt;code&gt;AnyWriter&lt;/code&gt; 不关心上下文的类型或 &lt;code&gt;write&lt;/code&gt; 返回的错误，这使得它可以与不同的实现类型一起使用。&lt;code&gt;GenericWriter&lt;/code&gt; 有一个将其自身转换为 &lt;code&gt;AnyWriter&lt;/code&gt; 的函数，如下所示：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;AnyWriter&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;writeFn&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;typeErasedWriteFn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;typeErasedWriteFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anyerror&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@alignCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;writeFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是一个使用 &lt;code&gt;File.Writer&lt;/code&gt; 通过 &lt;code&gt;AnyWriter&lt;/code&gt; 进行指针关系的可视化图：&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/AnyWriter-Diagram.svg&quot;&gt;
&lt;figcaption&gt;图形：File.Writer 和 AnyWriter 的指针关系图&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;File&lt;/code&gt; 和 &lt;code&gt;AnyWriter&lt;/code&gt; 都是运行时对象，&lt;code&gt;AnyWriter&lt;/code&gt; 使用 &lt;code&gt;File.Writer&lt;/code&gt; 提供的 &lt;code&gt;write&lt;/code&gt; 函数。&lt;/p&gt;&lt;p&gt;我们可以这样使用接口：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getStdOut&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;AnyWriter&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anyerror&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Hello, GenericWriter!&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是，运行时调度有一些缺点：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;它需要在运行时进行额外的工作，将上下文和 &lt;code&gt;writeFn&lt;/code&gt; 存储为指针。每次写入都必须跟随这些指针，需要额外的内存加载。&lt;/li&gt;&lt;li&gt;它通过返回 &lt;code&gt;anyerror&lt;/code&gt; 而不是固定的错误集来降低类型安全性，而固定的错误集允许穷举处理错误。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;考虑到这一点，让我们看看编译时调度是如何完成的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;anytype&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Zig 的 &lt;code&gt;anytype&lt;/code&gt; 关键字可以在函数签名中代替参数类型使用，以允许传递任何类型的参数。对于函数使用不同类型参数的每个实例，编译器会秘密生成一个使用该类型的具体函数。&lt;/p&gt;&lt;p&gt;这就是编译时调度的本质：我们可以编写可以与不同类型一起工作的代码，编译器会为每种使用的类型生成不同的代码。&lt;code&gt;anytype&lt;/code&gt; 用于许多用途，不仅限于接口，并且在 0.15.1 中仍然存在。&lt;/p&gt;&lt;p&gt;将我们现有的示例更改为使用 &lt;code&gt;anytype&lt;/code&gt; 看起来像这样：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getStdOut&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Hello, GenericWriter!&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以使用由 &lt;code&gt;GenericWriter&lt;/code&gt; 生成的 Writer 类型的任何值，甚至可以使用 &lt;code&gt;AnyWriter&lt;/code&gt; 作为参数传递。请注意，尝试传递一个类型没有 &lt;code&gt;Error&lt;/code&gt; 声明或 &lt;code&gt;write&lt;/code&gt; 函数的值会导致编译错误。&lt;/p&gt;&lt;p&gt;为每种正在使用的 Writer 类型生成代码消除了 &lt;code&gt;AnyWriter&lt;/code&gt; 表现出的运行时开销和类型安全问题。相反，编译时调度也有其自身的缺点：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;为每种类型生成单独的函数会增加生成的执行文件的大小。&lt;/li&gt;&lt;li&gt;从函数签名中不清楚可以使用哪些类型作为 &lt;code&gt;anytype&lt;/code&gt; 参数，通常需要注释来明确说明。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code&gt;anytype&lt;/code&gt; 的模糊性和泛型性使得 API 很容易只接受 &lt;code&gt;GenericWriter&lt;/code&gt; 的单个具体变体，例如 &lt;code&gt;std.http&lt;/code&gt;，它到目前为止一直使用 &lt;code&gt;std.net.Stream&lt;/code&gt;（用于网络套接字的 &lt;code&gt;GenericWriter&lt;/code&gt; 实现），并且不能与其他类型的 Writer 一起使用。&lt;/p&gt;&lt;p&gt;由于 &lt;code&gt;anytype&lt;/code&gt; 也允许 &lt;code&gt;AnyWriter&lt;/code&gt; 与之一起使用，因此它是此版本之前 Zig 标准库中接受 Writer 接口的主要方法。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;统一的 Writer&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;所有上述方法的新的替代方案是 0.15.1 的 &lt;code&gt;std.Io.Writer&lt;/code&gt;。它使用与 &lt;code&gt;AnyWriter&lt;/code&gt; 不同的动态调度方法，在接口中执行缓冲，并且具有相当多的额外功能和特性，这些功能和特性使其比以前的接口更复杂，但也更强大。&lt;/p&gt;&lt;p&gt;有关新接口背后的动机的简要列表可以在发行说明中找到，其中链接了 Zig 创建者 Andrew Kelley 的演讲，您绝对应该观看。&lt;/p&gt;&lt;p&gt;让我们深入了解一下这个接口是如何编写的（省略注释）。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;VTable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;VTable&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drain&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;splat&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;sendFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;file_reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Limit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FileError&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;unimplementedSendFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defaultFlush&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;rebase&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;preserve&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defaultRebase&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;哇。这里有很多要分解的东西。我稍后会解释 &lt;code&gt;buffer/end&lt;/code&gt; 字段，但让我们从 &lt;code&gt;vtable&lt;/code&gt; 开始，以及新 Writer 中的动态调度技术与旧的 &lt;code&gt;std.io.AnyWriter&lt;/code&gt; 中的动态调度技术的不同之处。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;虚表和 @fieldParentPtr&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;任何动态调度的接口都需要两件事：一种访问实现状态的方法，以及一组操作该状态以完成接口任务的函数指针。这组函数指针统称为虚表，或“vtable”。&lt;code&gt;AnyWriter&lt;/code&gt; 只有一个直接存储的函数指针。&lt;code&gt;Io.Writer&lt;/code&gt; 有一个更大的接口，因此存储了一个指向包含 4 个函数指针的虚表的指针。&lt;/p&gt;&lt;p&gt;在 &lt;code&gt;AnyWriter&lt;/code&gt; 中，指向实现对象的类型擦除指针存储在接口中。在新的 &lt;code&gt;Io.Writer&lt;/code&gt; 中，接口是实现对象的一个字段，并且指向该字段的指针被传递给函数。通过使用 Zig 内置的 &lt;code&gt;@fieldParentPtr&lt;/code&gt; 访问虚表函数中的实现状态，该函数从字段的指针中减去该字段在结构体内的偏移量。&lt;/p&gt;&lt;p&gt;这是一个帮助您理解这一切的图：&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/Io-Writer-Diagram.svg&quot;&gt;
&lt;figcaption&gt;图形：File.Writer 指针关系图&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;查看 &lt;code&gt;File.Writer&lt;/code&gt; 实现，注意接口是如何存储为一个字段的。像 &lt;code&gt;drain&lt;/code&gt; 这样的接口函数接受一个指向该字段的指针，并使用 &lt;code&gt;@fieldParentPtr&lt;/code&gt; 获取指向 &lt;code&gt;File.Writer&lt;/code&gt; 的指针。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// std.fs.File&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// ...&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;drain&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;io_w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;splat&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@alignCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@fieldParentPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;interface&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io_w&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;handle&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接口使用指向静态分配的虚表的指针构造，该虚表包含已实现的函数。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;initInterface&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtable&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drain&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;drain&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;sendFile&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;builtin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;zig_backend&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sendFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stage2_aarch64&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;unimplementedSendFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;buffer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在是时候讨论新 API 的主要功能了，即它如何处理缓冲。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;接口中的缓冲&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;缓冲是执行 IO 的一种广泛使用的优化方法。它涉及将数据存储在中间内存缓冲区中，并且仅在该缓冲区已满时才传输数据，从而减少了所需的数据传输总数。这提高了性能，因为传输数据通常很慢，例如，单个用于文件输出的 &lt;code&gt;syscall&lt;/code&gt; 比写入内存缓冲区慢 3 个数量级。&lt;/p&gt;&lt;p&gt;我们一直看到的 &lt;code&gt;drain&lt;/code&gt; 函数是实现实际写入缓冲数据的方式。用户完成 Writer 操作后，他们调用 &lt;code&gt;flush&lt;/code&gt; 来写出缓冲区中剩余的任何数据。&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/Buffering-Interface.svg&quot;&gt;
&lt;figcaption&gt;图形：展示 Io.Writer 如何缓存数据&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;在大多数语言中，缓冲是在后台完成的实现细节。Zig pre-writergate 具有 &lt;code&gt;std.io.BufferedWriter&lt;/code&gt;，它为此目的提供了一个 &lt;code&gt;GenericWriter&lt;/code&gt;。以下是如何使用它：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getStdOut&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffered_writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;bufferedWriter&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffered_writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffered_writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Hello, 0.14.1!&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在，缓冲是接口本身的一部分！Writer 接口对象中的 &lt;code&gt;buffer&lt;/code&gt; 和 &lt;code&gt;end&lt;/code&gt; 字段分别存储缓冲区和当前缓冲的数据量。&lt;/p&gt;&lt;p&gt;这是一个大胆的决定，因为将更多逻辑移动到接口中会降低其灵活性。没有其他可比的语言在接口中进行缓冲，但是这样做在性能方面实际上有好处。这是使用新 API 编写的先前示例：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;stdout&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;stdout_writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// this could also be done in `writeData`&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Hello, 0.15.1!&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那么，为什么这样更好呢？答案在于理解间接函数调用的性能。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;间接调用和虚调用&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;每个动态调度的接口，无论是什么语言，都涉及使用函数指针 (&lt;code&gt;*const fn&lt;/code&gt;) 来调用实现。像这样通过指针调用函数称为间接调用，如果函数指针恰好是虚表的一部分，则有时称为虚调用。&lt;/p&gt;&lt;p&gt;通常，间接调用比直接调用已知函数慢，原因有几个。间接调用意味着在调用函数之前加载函数的地址，而直接调用可以跳转到静态地址。间接调用也更难优化。如果编译器无法确定调用将转到哪个函数，则它无法内联该函数或使用调用站点的上下文执行其他有用的优化。&lt;/p&gt;&lt;p&gt;如果我们想要获得最佳性能，我们希望尽可能避免间接调用，这意味着尽可能少地调用 &lt;code&gt;drain&lt;/code&gt;。在接口中进行缓冲可以实现这一点，因为大多数写入操作都可以通过仅将其存储在缓冲区中而无需通过虚表来执行。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;drain 函数和向量 IO&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;drain&lt;/code&gt; 函数是接口的核心函数，因为它负责实际执行写入操作。它首先从缓冲区“排出”字节并写入它们，然后再写入传递给它的数据。它是唯一必须由实现者提供的函数。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drain&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;splat&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这比像 &lt;code&gt;GenericWriter&lt;/code&gt; 使用的标准 &lt;code&gt;write&lt;/code&gt; 函数奇怪得多。为什么 &lt;code&gt;data&lt;/code&gt; 是切片的切片而不是单个切片，&lt;code&gt;splat&lt;/code&gt; 的意义何在？&lt;/p&gt;&lt;p&gt;第一个问题可以用向量 IO 来回答。向量 IO 是指可以一次调用写入来自多个内存区域的数据。&lt;code&gt;data&lt;/code&gt; 参数称为“向量”，向量中的每个数据切片都由 &lt;code&gt;drain&lt;/code&gt; 顺序写入。这可能更有效，因为它减少了为写入不同的数据片段而进行多次虚调用的开销。&lt;code&gt;data&lt;/code&gt; 必须至少包含一个切片。&lt;/p&gt;&lt;p&gt;&lt;code&gt;splat&lt;/code&gt; 值是最后的数据切片将被写入的次数。这对于写入大量重复数据而不实际分配或复制任何内存非常有用。这也被称为“逻辑 &lt;code&gt;memset&lt;/code&gt;”。&lt;/p&gt;&lt;p&gt;重要的是要意识到 &lt;code&gt;drain&lt;/code&gt; 可以写入任意数量的字节。它可以写入所有字节，它可以写入缓冲区中的所有字节，但没有来自 &lt;code&gt;data&lt;/code&gt; 的字节，它可能只排出缓冲区的一部分。它返回它写入的字节数，不包括缓冲的字节，并且可能需要多次调用才能确保所有内容都被写入。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;sendFile&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这是将更多逻辑移动到接口以提高性能的另一个例子。提供 &lt;code&gt;sendFile&lt;/code&gt; 对于 &lt;code&gt;Io.Writer&lt;/code&gt; 完全是可选的，并且用于直接写入文件的内容。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;sendFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;file_reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Limit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FileError&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;unimplementedSendFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;源文件作为 &lt;code&gt;*File.Reader&lt;/code&gt;（&lt;code&gt;File.Writer&lt;/code&gt; 的对应方）传递，&lt;code&gt;limit&lt;/code&gt; 参数限制了应该从文件中读取多少数据。&lt;/p&gt;&lt;p&gt;某些操作系统具有用于将数据从文件复制到文件的 &lt;code&gt;syscall&lt;/code&gt;，而不会产生将数据传入和传出用户空间的开销。如果不支持，&lt;code&gt;sendFile&lt;/code&gt; 实现可以返回 &lt;code&gt;error.Unimplemented&lt;/code&gt;，用户可以默认手动读取和写入。&lt;code&gt;unimplementedSendFile&lt;/code&gt; 正是这样做的。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;flush 和 rebase&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;写入完成后，用户应调用 &lt;code&gt;flush&lt;/code&gt; 来写出缓冲区中剩余的任何数据。提供了默认实现作为 &lt;code&gt;defaultFlush&lt;/code&gt;，它只是重复调用 &lt;code&gt;drain&lt;/code&gt; 直到缓冲区为空，这通常是所需的方法，但实现可以提供其自己的函数来实现自定义行为。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defaultFlush&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;rebase&lt;/code&gt; 用于确保可以缓冲一定量的数据，类似于 &lt;code&gt;arraylist&lt;/code&gt; 上的 &lt;code&gt;ensureCapacity&lt;/code&gt;。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;rebase&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;preserve&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defaultRebase&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们还可以使用 &lt;code&gt;preserve&lt;/code&gt; 指定应保留多少个最近的字节。&lt;/p&gt;&lt;p&gt;默认的 &lt;code&gt;rebase&lt;/code&gt; 通过重复调用 &lt;code&gt;drain&lt;/code&gt; 以在保留区域之前写出字节，然后将保留的字节向后复制以保持连续来工作。这是一个小规模的示例，说明它可能是什么样子：&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/Rebase-Diagram.svg&quot;&gt;
&lt;figcaption&gt;图形：rebase 在小缓冲区上的工作方式&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;结论&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这篇文章已经太长了，所以我将在这里停止，但是希望您对使用新 Writer 接口时在底层发生的事情有一个不错的心理模型。关于 &lt;code&gt;std.Io.Writer&lt;/code&gt; 还有很多东西要学习（更不用说它的 Reader 对应物了），但是熟悉它的唯一方法是在您自己的代码中使用它。&lt;/p&gt;&lt;p&gt;新的接口比以前更复杂，更难以学习，但是掌握它应该可以帮助您编写性能更高的 IO 代码。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2025-09-17-new-writer/</link>
        <pubDate>Wed, 17 Sep 2025 01:03:06 +0000</pubDate>
        <guid>https://ziglang.cc/post/2025-09-17-new-writer/</guid>
      </item>
    
      <item>
        <title>ZigCC 网站迁移至 Zine 实战复盘</title>
        <description>&lt;p&gt;本文复盘了 ZigCC 社区网站从 Hugo 迁移至 Zine 的全过程，旨在分享其中的经验与思考，为有类似需求的朋友提供参考。&lt;/p&gt;&lt;h2 id=&quot;why-choose-zine&quot;&gt;一、为何选择 Zine？&lt;/h2&gt;&lt;p&gt;我们最初使用 Hugo 及其 Docsy 主题搭建网站，但在使用过程中遇到了一些痛点，促使我们寻找新的解决方案。选择迁移至 Zine 主要基于以下几点考量：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;解决 Hugo 的既有问题&lt;/strong&gt;：Hugo 本身非常强大，但在某些细节上存在问题，例如 Markdown 在页脚（footer）中的解析行为不符合预期。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;追求现代设计美学&lt;/strong&gt;：Docsy 主题乃至 Hugo 的部分生态，在技术和审美上略显陈旧。我们希望网站风格更加现代化、简约。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;更精细的代码高亮&lt;/strong&gt;：主流高亮库如 &lt;code&gt;highlight.js&lt;/code&gt;, &lt;code&gt;prism.js&lt;/code&gt; 和 &lt;code&gt;shiki.js&lt;/code&gt; 中，&lt;code&gt;shiki.js&lt;/code&gt; 效果最佳。然而，Zine 对 Zig 代码的语法高亮比它们更为细致，提供了更强的自定义控制能力。（代价是 Zine 对其他语言的解析支持尚不完善，其底层似乎是调用 tree-sitter 实现的）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;灵活的内容格式生成&lt;/strong&gt;：Zine 的布局（Layout）和 Scripty API 赋予了项目结构极大的灵活性，使得未来生成 PDF 或其他格式的文档变得可行，RSS Feed 的生成也同样受益。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;显著的性能提升&lt;/strong&gt;：迁移后，无论是后端的构建速度还是前端的渲染性能都有了明显提升。这部分也得益于 Zine 架构带来的项目结构简化。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;当然，还有一个至关重要的原因：&lt;strong&gt;拥抱并反哺 Zig 生态&lt;/strong&gt;。正如 ZigCC 发起者刘家财所说：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“如果我们自己都不用，那更不会有别人用了。”&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;作为 Zig 社区的一份子，我们有责任参与到生态建设中。果不其然，这次迁移过程也让我们发现了 Zine 的一些待解决问题和潜在的改进点。&lt;/p&gt;&lt;h2 id=&quot;interpretation-of-zines-core-concepts&quot;&gt;二、Zine 核心概念解读&lt;/h2&gt;&lt;p&gt;Zine 是一个现代、高效的静态网站生成器。要理解它，首先要掌握其核心设计理念和文件结构。&lt;/p&gt;&lt;h3 id=&quot;project-structure-and-configuration&quot;&gt;项目结构与配置&lt;/h3&gt;&lt;p&gt;一个基础的 Zine 项目结构与 Hugo 等主流生成器类似，主要包含内容、布局和静态资源目录：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;sh&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;assets/&lt;/span&gt;      &lt;span class=&quot;comment&quot;&gt;# 存放 CSS、图片等静态资源&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;content/&lt;/span&gt;     &lt;span class=&quot;comment&quot;&gt;# 存放网站内容，通常是 smd 文件&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│  &lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;about.smd&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│  &lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;└──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;index.smd&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;layouts/&lt;/span&gt;     &lt;span class=&quot;comment&quot;&gt;# 存放布局模板，每个 smd 文件都对应一个 shtml 布局&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│  &lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;index.shtml&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│  &lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;page.shtml&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│  &lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;└──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;templates/&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;# 模板可以被其他布局继承，以实现代码复用&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│  &lt;/span&gt;     &lt;span class=&quot;constant&quot;&gt;└──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;base.shtml&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;└──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;zine.ziggy&lt;/span&gt;   &lt;span class=&quot;comment&quot;&gt;# Zine 项目的全局配置文件&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;项目的核心是 &lt;code&gt;zine.ziggy&lt;/code&gt; 配置文件，它定义了网站的元数据和目录路径。以 ZigCC 的配置为例：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Site&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Zig 语言中文社区&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;host_url&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;https://ziglang.cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;content_dir_path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;layouts_dir_path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;layouts&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;assets_dir_path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;assets&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;static_assets&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;content-rendering&quot;&gt;内容渲染：SuperMD、SuperHTML 与 Scripty&lt;/h3&gt;&lt;p&gt;Zine 在内容渲染上采用了与 Hugo 截然不同的哲学。它没有直接使用标准的 Markdown 和 HTML，而是引入了三个核心概念：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://zine-ssg.io/docs/supermd/&quot; target=&quot;_blank&quot;&gt;SuperMD&lt;/a&gt;&lt;/strong&gt;: 一种扩展版的 Markdown。它解决了原生 Markdown 难以表达复杂结构（需内联 HTML）的痛点，允许开发者嵌入资源和定义更丰富的语义结构。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://zine-ssg.io/docs/superhtml&quot; target=&quot;_blank&quot;&gt;SuperHTML&lt;/a&gt;&lt;/strong&gt;: 一种专为模板设计的扩展版 HTML。其设计目标是“从根本上杜绝生成语法错误的 HTML”，将大量潜在的运行时错误提前到构建时发现。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://zine-ssg.io/docs/scripty/&quot; target=&quot;_blank&quot;&gt;Scripty&lt;/a&gt;&lt;/strong&gt;: 驱动前两者的微型表达式语言。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;本质上，SuperMD 和 SuperHTML 就是内嵌了 Scripty 动态能力的 Markdown 和 HTML。Scripty 的语法简洁，专为字符串嵌入而设计，是实现 Zine 动态内容的关键。&lt;/p&gt;&lt;h3&gt;Scripty 快速入门&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;所有表达式都以 ` 符号开头。&lt;/li&gt;&lt;li&gt;支持链式字段访问：&lt;code&gt;$foo.bar.baz&lt;/code&gt;&lt;/li&gt;&lt;li&gt;支持函数调用：&lt;code&gt;$foo.bar.qux(&amp;apos;arg1&amp;apos;, &amp;quot;arg2&amp;quot;)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;支持字符串、数字、布尔等基本字面量。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;下面是一个简单的示例，展示 Scripty 如何在 SuperHTML 和 SuperMD 中工作：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SuperHTML 示例：&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;about&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;$site.page(&amp;apos;about&amp;apos;)&lt;/span&gt;&amp;quot;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;href&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;$ctx.about.link()&lt;/span&gt;&amp;quot; &lt;span class=&quot;attribute&quot;&gt;text&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;$ctx.about.title&lt;/span&gt;&amp;quot;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;SuperMD 示例：&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;markdown&quot;&gt;Check out our [about page]($link.page(&amp;apos;about&amp;apos;)).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Scripty 作为表达式语言，其威力在条件和嵌套逻辑中得以体现：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;class&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;{$page.title.len().gt(25).then(&amp;apos;long-title&amp;apos;)}&lt;/span&gt;&amp;quot;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;...&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在上述代码中，如果页面标题长度大于 25 个字符，&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; 标签就会被赋予 &lt;code&gt;long-title&lt;/code&gt; 这个 class。&lt;/p&gt;&lt;p&gt;通过这三者的结合，Zine 在保证内容与布局分离的同时，提供了高度的灵活性和安全性。更详细的用法，推荐阅读 Zine 官方文档。&lt;/p&gt;&lt;h2 id=&quot;detailed-explanation-of-migration-steps&quot;&gt;三、迁移步骤详解&lt;/h2&gt;&lt;p&gt;整个迁移过程可以分为内容转换、布局设计、预览调试和最终部署几个关键步骤。&lt;/p&gt;&lt;h3 id=&quot;content-format-conversion&quot;&gt;内容格式转换&lt;/h3&gt;&lt;p&gt;迁移的核心工作是将原有内容（本文中主要是 Markdown 和 Org Mode 文件）转换为 Zine 支持的 SuperMarkdown (&lt;code&gt;.smd&lt;/code&gt;) 格式。&lt;/p&gt;&lt;p&gt;起初，我尝试让 AI 编写 &lt;code&gt;md&lt;/code&gt; 到 &lt;code&gt;smd&lt;/code&gt; 的转换脚本，效果尚可。但对于结构更复杂的 Org Mode 文件，脚本难以胜任，因此最终转向使用 Pandoc。&lt;/p&gt;&lt;p&gt;以下是使用 Pandoc 将 &lt;code&gt;.org&lt;/code&gt; 文件批量转换为 Markdown 格式（并重命名为 &lt;code&gt;.smd&lt;/code&gt;）的 Fish 脚本，此方法同样适用于 &lt;code&gt;.md&lt;/code&gt; 文件：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;fish&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 注意：这里实际上是转换到了 GitHub Flavored Markdown (gfm) 格式&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;# 后续仍需手动调整以完全适配 smd 语法&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; f &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; *.org
  &lt;span class=&quot;punctuation_bracket function&quot;&gt;pandoc&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;$f&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;gfm&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket function&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;change-extension&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;smd&amp;quot;&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;$f&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;手动适配要点&lt;/strong&gt;：&lt;/p&gt;&lt;p&gt;Pandoc 完成初步转换后，仍需手动调整以适配 &lt;code&gt;.smd&lt;/code&gt; 和 &lt;code&gt;.shtml&lt;/code&gt; 的专属语法。常见差异包括：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;HTML 嵌入&lt;/strong&gt;：&lt;code&gt;.smd&lt;/code&gt; 不推荐直接嵌入 HTML。相关代码需要用 &lt;code&gt; ```=html&lt;/code&gt; 代码块包裹。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;章节标题链接&lt;/strong&gt;：标题不会自动生成 ID 和锚点链接，需要手动使用 &lt;code&gt;$heading.id(&amp;quot;custom-id&amp;quot;)&lt;/code&gt; 添加（注意 ID 不能包含空格）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;资源引用&lt;/strong&gt;：可以使用 Scripty API 或将资源放在 &lt;code&gt;public&lt;/code&gt; 目录下通过绝对路径 (&lt;code&gt;/path/to/resource&lt;/code&gt;) 引用。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;建议先完成布局文件的编写，在实时预览的环境下再进行这些细致的手动适配，效率更高。&lt;/p&gt;&lt;h3 id=&quot;processing-frontmatter&quot;&gt;处理 Frontmatter&lt;/h3&gt;&lt;p&gt;Zine 使用 Ziggy 语法作为 Frontmatter 的格式，它与 Zig 语法高度相似。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href=&quot;https://ziggy-lang.io/&quot; target=&quot;_blank&quot;&gt;Ziggy 官网&lt;/a&gt; 提供了一个方便的 &lt;a href=&quot;https://ziggy-lang.io/documentation/ziggy-convert/&quot; target=&quot;_blank&quot;&gt;在线转换器&lt;/a&gt;，可以将 YAML、TOML 或 JSON 格式的 Frontmatter 转换为 Ziggy。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;一个典型的 &lt;code&gt;.smd&lt;/code&gt; 文件 Frontmatter 如下：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Zig comptime&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@date&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;2025-01-23T12:00:00+08:00&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;author&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;xihale&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;layout&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;post.shtml&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;draft&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;design-layout&quot;&gt;设计布局&lt;/h3&gt;&lt;p&gt;由于我们希望采用全新的简约风格，因此我没有沿用 Docsy 的样式，而是重新设计了一套布局。目前的版本虽已上线，但在目录（TOC）等细节上仍有优化空间。&lt;/p&gt;&lt;p&gt;Zine 布局有几个关键特性：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;ID Slot&lt;/strong&gt;：Zine 采用 &lt;a href=&quot;https://zine-ssg.io/docs/superhtml/#super&quot; target=&quot;_blank&quot;&gt;ID Slot&lt;/a&gt; 机制，比传统的 Slot 更灵活。例如，你可以将 &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 和内容区的 Slot 分开处理，从而实现对资源加载等操作的精细控制。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;&amp;lt;ctx&amp;gt;&lt;/code&gt; 标签&lt;/strong&gt;：合理使用 &lt;code&gt;&amp;lt;ctx&amp;gt;&lt;/code&gt; 标签可以简化模板的逻辑和组织结构。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;此外，你还可以通过在 &lt;code&gt;.smd&lt;/code&gt; 的 Frontmatter 中定义 &lt;code&gt;.custom&lt;/code&gt; 字段，向布局传递自定义参数，实现更细粒度的控制。&lt;/p&gt;&lt;p&gt;例如，在 &lt;code&gt;.smd&lt;/code&gt; 中启用数学公式支持：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// file: content/your-post.smd&lt;/span&gt;
&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;custom&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;math&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在布局文件中根据此标志加载 KaTeX 库：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;// file: layouts/post.shtml
&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;:if&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;$page.custom.getOr(&amp;apos;math&amp;apos;, false)&lt;/span&gt;&amp;quot;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;link&lt;/span&gt;
    &lt;span class=&quot;attribute&quot;&gt;href&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;https://cdnjs.webstatic.cn/ajax/libs/KaTeX/0.16.9/katex.min.css&lt;/span&gt;&amp;quot;
    &lt;span class=&quot;attribute&quot;&gt;rel&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;stylesheet&lt;/span&gt;&amp;quot;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;script&lt;/span&gt;
    &lt;span class=&quot;attribute&quot;&gt;defer&lt;/span&gt;
    &lt;span class=&quot;attribute&quot;&gt;src&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;https://cdnjs.webstatic.cn/ajax/libs/KaTeX/0.16.9/katex.min.js&lt;/span&gt;&amp;quot;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;script&lt;/span&gt;
    &lt;span class=&quot;attribute&quot;&gt;defer&lt;/span&gt;
    &lt;span class=&quot;attribute&quot;&gt;src&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;https://cdnjs.webstatic.cn/ajax/libs/KaTeX/0.16.9/contrib/auto-render.min.js&lt;/span&gt;&amp;quot;
    &lt;span class=&quot;attribute&quot;&gt;onload&lt;/span&gt;=&amp;quot;&lt;span class=&quot;string&quot;&gt;renderMathInElement(document.body);&lt;/span&gt;&amp;quot;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;preview-and-debugging&quot;&gt;预览与调试&lt;/h3&gt;&lt;p&gt;完成布局和初步内容转换后，就进入了最繁琐的环节：预览、检查和修正。&lt;/p&gt;&lt;p&gt;运行 &lt;code&gt;zine&lt;/code&gt; 命令启动本地服务器，实时预览网站效果。逐一检查每篇文章的渲染情况，发现格式错误或显示异常的地方，返回 &lt;code&gt;.smd&lt;/code&gt; 文件进行修改。&lt;/p&gt;&lt;p&gt;这一步需要极大的耐心，几乎等同于重新校对所有文章。需要注意的是，Zine 目前仍在快速发展中，部分功能的报错信息可能不够明确，需要结合文档和实践耐心排查。&lt;/p&gt;&lt;h3 id=&quot;deployment&quot;&gt;部署&lt;/h3&gt;&lt;p&gt;Zine 官方文档提供了详细的部署指南：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://zine-ssg.io/docs/deploying/github-pages/&quot; target=&quot;_blank&quot;&gt;Deploying to GitHub Pages&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://zine-ssg.io/docs/deploying/cloudflare-pages/&quot; target=&quot;_blank&quot;&gt;Deploying to Cloudflare Pages&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;你可以参考 zine-ssg 或本站（ZigCC）仓库中的 GitHub Actions 配置来设置自己的自动化部署流程。&lt;/p&gt;&lt;h2 id=&quot;summary-and-experience-sharing&quot;&gt;四、总结与经验分享&lt;/h2&gt;&lt;p&gt;最后，分享几点额外的经验：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;SuperHTML (&lt;code&gt;.shtml&lt;/code&gt;) 对 HTML 语法有严格的要求，它不仅仅是 HTML 的超集。某些写法可能与个人习惯冲突，需要适应其规范。&lt;/li&gt;&lt;li&gt;Scripty API 采用链式调用语法，非常灵活。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;迁移过程中遇到问题时，不要慌张。首先仔细查看终端的报错信息，然后查阅官方文档，最后可以多翻阅 zine-ssg 和 ziglang.org 等同样使用 Zine 构建的网站源码，它们是最好的学习范例。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2025-07-19-zine-migration/</link>
        <pubDate>Sat, 19 Jul 2025 00:00:00 +0000</pubDate>
        <guid>https://ziglang.cc/post/2025-07-19-zine-migration/</guid>
      </item>
    
      <item>
        <title>0.14 版本更新介绍</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://ziglang.org/download/0.14.0/release-notes.html&quot; target=&quot;_blank&quot;&gt;https://ziglang.org/download/0.14.0/release-notes.html&lt;/a&gt;&lt;/p&gt;&lt;h2 id=&quot;release-overview&quot;&gt;发布概览&lt;/h2&gt;&lt;p&gt;Zig 0.14.0 版本是经过 &lt;strong&gt;9 个月的工作&lt;/strong&gt;，由 &lt;strong&gt;251 位不同的贡献者&lt;/strong&gt; 完成，包含 &lt;strong&gt;3467 个提交&lt;/strong&gt; 的成果。该版本专注于提升 &lt;strong&gt;健壮性&lt;/strong&gt;、&lt;strong&gt;最优性&lt;/strong&gt; 和 &lt;strong&gt;可重用性&lt;/strong&gt;，并通过 Zig 软件基金会 (Zig Software Foundation) 资助开发。&lt;/p&gt;&lt;h2 id=&quot;key-topics-and-updates&quot;&gt;核心主题与重要更新&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;提升编译速度与开发效率：&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;版本说明强调了两个重要的长期投资：&lt;strong&gt;增量编译 (Incremental Compilation)&lt;/strong&gt; 和 &lt;strong&gt;快速 x86 后端 (fast x86 Backend)&lt;/strong&gt;。&lt;/li&gt;&lt;li&gt;这两项投资的核心目标是 &lt;strong&gt;“reducing edit/compile/debug cycle latency”&lt;/strong&gt;（减少编辑/编译/调试循环延迟）。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;增量编译&lt;/strong&gt; 功能在本次发布中可以通过 -fincremental 标志选择启用，但目前尚未完全成熟。它在配合文件系统监控时表现良好，尤其是在仅检查编译错误时能显著提升反馈速度。&lt;/li&gt;&lt;li&gt;引用：$ zig build -Dno-bin -fincremental –watch (展示了在大型代码库中快速获得编译错误反馈的示例)。&lt;/li&gt;&lt;li&gt;目前不兼容 usingnamespace，建议用户尽量避免使用。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;x86 后端&lt;/strong&gt; 在行为测试中表现出色，已经通过了 98% 的测试用例，编译速度显着快于 LLVM 后端，并且支持更好的调试器。它有望在下一个发布周期成为调试模式下的默认后端。可以通过 -fno-llvm 或 use_llvm = false 启用。&lt;/li&gt;&lt;li&gt;引用：The x86 backend is now passing 1884/1923 (98%) of the behavior test suite compared to the LLVM backend.&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;增强目标平台支持 (Target Support)：&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;这是一个主要主题，Zig 的跨平台编译能力得到了极大扩展。&lt;/li&gt;&lt;li&gt;版本说明详细列出了不同目标平台在语言特性、标准库、代码生成、链接器、调试信息、libc 和 CI 测试等方面的支持级别，采用分层系统 (Tier System) 进行分类（Tier 1 为最高级别）。&lt;/li&gt;&lt;li&gt;引用：A major theme in this Zig release is improved target support; the list of targets that Zig can correctly cross-compile to and run on has been greatly expanded.&lt;/li&gt;&lt;li&gt;对 arm/thumb, mips/mips64, powerpc/powerpc64, riscv32/riscv64, 或 s390x 等目标平台的工具链问题、标准库支持缺失和崩溃问题有了显著改进。&lt;/li&gt;&lt;li&gt;更新了目标三元组 (Target Triple Changes) 的命名和支持，以更准确地反映不同平台（如 Windows、Linux 使用 musl libc）的 ABI 和特性。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;重要的语言特性变化 (Language Changes)：&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;标记 switch (Labeled Switch):&lt;/strong&gt; 允许 switch 语句拥有标签并被 continue 语句指向，从而实现更清晰的状态机实现。关键动机在于生成优化后的代码，特别是通过不同的分支指令帮助 CPU 进行更准确的分支预测，提升性能。&lt;/li&gt;&lt;li&gt;引用：Zig 0.14.0 implements an accepted proposal which allows switch statements to be labeled, and to be targeted by continue statements.&lt;/li&gt;&lt;li&gt;引用：This language construct is designed to generate code which aids the CPU in predicting branches between cases of the switch, allowing for increased performance in hot loops…&lt;/li&gt;&lt;li&gt;更新 Zig 的 tokenizer 利用此特性带来了 13% 的性能提升。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;声明字面量 (Decl Literals):&lt;/strong&gt; 扩展了 .foo 语法，不仅可以引用枚举成员，还可以引用目标类型上的任何声明 (const/var/fn)。这使得初始化结构体字段和调用初始化函数更加简洁和安全，特别是避免了无效的默认字段值问题。&lt;/li&gt;&lt;li&gt;引用：Zig 0.14.0 extends the “enum literal” syntax (.foo) to provide a new feature, known as “decl literals”.&lt;/li&gt;&lt;li&gt;许多现有使用字段默认值的地方可能更适合使用 default 或 empty 等声明来处理，以确保数据不变性。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;字段和声明不能共享名称 (Fields and Declarations Cannot Share Names):&lt;/strong&gt; 引入了容器类型（struct, union, enum, opaque）的字段和声明不能同名的限制，解决了歧义问题并便于文档生成。&lt;/li&gt;&lt;li&gt;引用：Zig 0.14.0 introduces a restriction that container types (struct , union , enum and opaque ) cannot have fields and declarations ( const / var / fn ) with the same names.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;@splat 支持数组 (@splat Supports Arrays):&lt;/strong&gt; 扩展了 @splat 内置函数，使其可以应用于数组和哨兵终止数组，方便用常量值初始化数组。&lt;/li&gt;&lt;li&gt;引用：Zig 0.14.0 expands the @splat builtin to apply not only to vectors, but to arrays.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;全局变量可以相互引用地址 (Global Variables can be Initialized with Address of Each Other):&lt;/strong&gt; 允许全局变量在初始化时相互引用地址。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;@export 操作数现在是指针 (@export Operand is Now a Pointer):&lt;/strong&gt; @export 内置函数现在接受一个指针作为操作数，使其用法更清晰和一致，通常只需在旧用法前添加 &amp;。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;新的 @branchHint 内置函数，取代 @setCold (New @branchHint Builtin, Replacing @setCold):&lt;/strong&gt; 引入 @branchHint 内置函数，允许开发者向优化器提示分支的可能性，有 .none, .likely, .unlikely, .cold, .unpredictable 等选项。这取代了旧的 @setCold。&lt;/li&gt;&lt;li&gt;引用：Zig 0.14.0 introduces a mechanism to communicate this information: the new @branchHint(comptime hint: std.builtin.BranchHint) builtin.&lt;/li&gt;&lt;li&gt;@branchHint 必须是其所在块或函数的第一个语句。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;移除 @fenceStoreLoad Barriers:&lt;/strong&gt; 移除 @fence(.StoreLoad)，其功能现在可以通过使用 SeqCst 或 Acquire/Release 原子操作来实现。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Packed Struct Equality 和 Packed Struct Atomics:&lt;/strong&gt; 允许直接对 Packed Struct 进行相等性比较和原子操作，不再需要 @bitCast 到底层整数类型。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;@ptrCast 允许改变切片长度 (@ptrCast Allows Changing Slice Length):&lt;/strong&gt; #22706&lt;/li&gt;&lt;li&gt;&lt;strong&gt;移除匿名结构体类型，统一元组 (Remove Anonymous Struct Types, Unify Tuples):&lt;/strong&gt; 重构匿名结构体字面量和元组的工作方式，使其使用”普通”结构体类型和基于 AST 节点及结构体的等价性。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Calling Convention 增强和 @setAlignStack 被取代 (Calling Convention Enhancements and @setAlignStack Replaced):&lt;/strong&gt; std.builtin.CallingConvention 现在是一个标记联合，包含更多目标平台特定的调用约定，并允许通过 CommonOptions 设置栈对齐等选项。.c 调用约定现在是一个声明，可以通过 callconv(.c) 使用 Decl Literals 访问。@setAlignStack 被移除，其功能现在通过调用约定的选项实现。&lt;/li&gt;&lt;li&gt;*&lt;em&gt;std.builtin.Type 字段重命名和简化 (std.builtin.Type Fields Renamed and Simplify Usage Of ?const anyopaque):&lt;/em&gt; std.builtin.Type 联合体的字段名称改为小写，并增加了对 default_value_ptr 和 sentinel_ptr 字段的 helper 方法，以简化使用。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;不允许非标量哨兵类型 (Non-Scalar Sentinel Types Disallowed):&lt;/strong&gt; 哨兵值现在只能是支持 == 操作符的标量类型。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;@FieldType 内置函数 (@FieldType builtin):&lt;/strong&gt; 新增 @FieldType 内置函数，用于获取给定类型和字段名称的字段类型，取代了 std.meta.FieldType 函数。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;@src 获得 Module 字段 (@src Gains Module Field):&lt;/strong&gt; std.builtin.SourceLocation 结构体新增 module 字段。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;@memcpy 规则调整 ( @memcpy Rules Adjusted):&lt;/strong&gt; langspec 定义调整，源和目标元素类型必须内存可强制转换，从而确保是原始复制操作。对 comptime @memcpy 增加了别名检查和更高效的实现。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;禁止不安全的内存强制转换 (Unsafe In-Memory Coercions Disallowed):&lt;/strong&gt; #22243&lt;/li&gt;&lt;li&gt;&lt;strong&gt;callconv, align, addrspace, linksection 不能引用函数参数 (#22264callconv, align, addrspace, linksection Cannot Reference Function Arguments):&lt;/strong&gt; #22264&lt;/li&gt;&lt;li&gt;&lt;strong&gt;函数调用的分支配额规则调整 (Branch Quota Rules Adjusted for Function Calls):&lt;/strong&gt; #22414&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;标准库改进 (Standard Library)：&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;DebugAllocator 和 SmpAllocator:&lt;/strong&gt; 重写了 GeneralPurposeAllocator 并更名为 DebugAllocator，提高了调试模式下的性能。新增了 SmpAllocator，一个针对 ReleaseFast 模式和多线程优化的单例分配器，性能可与 glibc 媲美。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Allocator API 变化 (remap):&lt;/strong&gt; std.mem.Allocator.VTable 新增了 remap 函数，允许在可能的情况下进行无需 memcpy 的内存重映射。resize 语义不变。Allocator.VTable 函数现在使用 std.mem.Alignment 类型。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ZON 解析和序列化 (ZON Parsing and Serialization):&lt;/strong&gt; std.zon.parse 提供运行时解析 ZON 到 Zig 结构体的功能，std.zon.stringify 提供运行时序列化功能。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;运行时页面大小 (Runtime Page Size):&lt;/strong&gt; 移除了编译时已知的 std.mem.page_size，代之以编译时已知的 std.heap.page_size_min 和 std.heap.page_size_max。std.heap.pageSize() 提供运行时实际页面大小。解决了在 Apple 新硬件上运行 Linux 的支持问题。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Panic 接口 (#22594Panic Interface):&lt;/strong&gt; #22594&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Transport Layer Security (std.crypto.tls):&lt;/strong&gt; #21872&lt;/li&gt;&lt;li&gt;&lt;strong&gt;process.Child.collectOutput API 变化 (#21872process.Child.collectOutput API Changed):&lt;/strong&gt; API 签名改变，现在将 allocator 作为第一个参数传入。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;LLVM Builder API:&lt;/strong&gt; LLVM bitcode builder API 移至 std.zig.llvm，方便第三方项目复用。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;拥抱”非管理”风格容器 (Embracing “Unmanaged”-Style Containers):&lt;/strong&gt; 大部分带有内置 allocator 的标准库容器（如 std.ArrayList, std.ArrayHashMap）已被弃用，推荐使用”非管理”风格容器（如 std.ArrayListUnmanaged, std.ArrayHashMapUnmanaged），并在需要时显式传递 allocator。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;std.c 重组 (std.c Reorganization):&lt;/strong&gt; 重组了 std.c，使其结构更清晰，并改变了对不存在符号的处理方式（从 @compileError 改为 void 或 {}），移除了标准库中最后一个 usingnamespace 的使用点。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;弃用列表 (List of Deprecations):&lt;/strong&gt; 列出了大量被弃用或重命名的标准库函数和类型。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Binary Search:&lt;/strong&gt; #20927&lt;/li&gt;&lt;li&gt;&lt;strong&gt;std.hash_map 获得 rehash 方法 (#20927std.hash_map gains a rehash method):&lt;/strong&gt; 为解决 HashMap 移除元素后的性能下降问题新增了 rehash 方法（Array Hash Map 没有此问题）。此方法预计在未来不再需要时会被删除。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;构建系统升级 (Build System)：&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;基于现有模块创建 Artifacts (Creating Artifacts from Existing Modules):&lt;/strong&gt; 修改了构建系统 API，允许从现有的 std.Build.Module 对象创建 Compile 步骤，使模块图的定义更清晰，组件复用更容易。旧的 API 用法已被弃用。&lt;/li&gt;&lt;li&gt;引用：Zig 0.14.0 modifies the build system APIs for creating Compile steps, allowing them to be created from existing std.Build.Module objects.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;允许包按名称暴露任意 LazyPath (Allow Packages to Expose Arbitrary LazyPaths by Name):&lt;/strong&gt; 新增 std.Build.addNamedLazyPath 和 std.Build.Module.namedLazyPath 方法，允许依赖包按名称暴露生成的 LazyPath 给其依赖者使用。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;addLibrary 函数：&lt;/strong&gt; 新增 addLibrary 函数，取代 addSharedLibrary 和 addStaticLibrary，使得在 build.zig 中更容易切换链接模式，并与 linkLibrary 名称更匹配。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;文件系统监控 (File System Watching):&lt;/strong&gt; #22105&lt;/li&gt;&lt;li&gt;&lt;strong&gt;新包哈希格式 (New Package Hash Format):&lt;/strong&gt; 引入新的包哈希格式，包含 32 位 id 和 32 位校验和，用于在去中心化生态系统中唯一标识包。当 fork 项目时，如果上游仍维护，应该重新生成 fingerprint。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;WriteFile Step, RemoveDir Step, Fmt Step:&lt;/strong&gt; 新增或改进了这些构建步骤。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Breakings:&lt;/strong&gt; 多个 installHeader 和 installHeadersDirectory 相关函数签名改变，现在接受 LazyPath。生成的 -femit-h 头文件不再默认发出。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;编译器和链接器改进 (Compiler and Linker)：&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;多线程后端支持 (Multithreaded Backend Support):&lt;/strong&gt; 部分编译器后端（如 x86 后端）支持在单独线程中运行代码生成，显著提升了编译速度。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;LLVM 19:&lt;/strong&gt; 升级到 LLVM 19.1.7。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;链接器输入文件解析移至前端 (Move Input File Parsing to the Frontend):&lt;/strong&gt; 将 GNU ld 脚本处理移至前端，以便在编译开始时了解所有链接器输入，实现编译和链接同时进行。为了避免对所有 .so 文件进行文件系统访问，新增了 -fallow-so-scripts 命令行标志，允许用户选择启用对 .so 脚本的支持。&lt;/li&gt;&lt;li&gt;引用：Moves GNU ld script processing to the frontend to join the relevant library lookup logic, making the libraries within subject to the same search criteria as all the other libraries.&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;集成模糊测试器 (Fuzzer)：&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;Zig 0.14.0 集成了一个模糊测试器，目前处于 alpha 状态。通过 –fuzz 命令行选项启用。&lt;/li&gt;&lt;li&gt;可以针对包含 std.testing.fuzz 的单元测试二进制文件进行进程内模糊测试。&lt;/li&gt;&lt;li&gt;提供了 Web UI (&lt;a href=&quot;http://127.0.0.1:38239/&quot; target=&quot;_blank&quot;&gt;http://127.0.0.1:38239/&lt;/a&gt;) 显示实时代码覆盖率。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Bug 修复与 Toolchain 更新 (Bug Fixes and Toolchain)：&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;关闭了 416 个 bug 报告。但版本说明坦承 &lt;strong&gt;“This Release Contains Bugs”&lt;/strong&gt;，并指出在 1.0.0 版本达到 Tier 1 支持时会增加 bug 策略。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;UBSan Runtime:&lt;/strong&gt; Debug 模式下默认启用 UBSan 运行时库，为 C 代码的未定义行为提供更详细的恐慌信息和堆栈跟踪。可以通过 -fno-ubsan-rt 和 -fubsan-rt 控制。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;compiler_rt:&lt;/strong&gt; 包含了优化的 memcpy 实现。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;musl 1.2.5:&lt;/strong&gt; 捆绑的 musl 更新并应用了 CVE 修复和目标平台特定补丁。不再捆绑 musl 的 memcpy 文件，而是使用 Zig 的优化实现。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;glibc 2.41:&lt;/strong&gt; 支持 glibc 2.40 和 2.41 交叉编译，修复了多个与 glibc 相关的问题。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Linux 6.13.4 Headers, Darwin libSystem 15.1, MinGW-w64, wasi-libc:&lt;/strong&gt; 更新了捆绑的操作系统头文件和 libc 版本。捆绑了 winpthreads 库。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;社区贡献与资助：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;版本说明详细感谢了 &lt;strong&gt;251 位&lt;/strong&gt; 为本次发布做出贡献的开发者。&lt;/li&gt;&lt;li&gt;特别感谢了通过经常性捐赠支持 Zig 的个人和组织赞助商，强调了开源社区驱动的重要性。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;路线图展望：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;版本说明中穿插提到了未来的一些计划，例如提升增量编译的成熟度、使 x86 后端成为调试模式下的默认选项、改进 ZON 导入，以及未来容器和哈希地图的改进。&lt;/li&gt;&lt;li&gt;最终目标是达到 1.0.0 版本，届时 Tier 1 支持将包含 bug 政策。&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;faq-zig-0-14-0&quot;&gt;关于 Zig 0.14.0 版本的常见问题解答&lt;/h2&gt;&lt;h3 id=&quot;main-updates-and-highlights&quot;&gt;Zig 0.14.0 版本的主要更新和亮点是什么？&lt;/h3&gt;&lt;p&gt;Zig 0.14.0 版本是长达 9 个月开发工作和 3467 次提交的成果，主要亮点包括：显著增强了对多种目标平台的支持，包括 arm/thumb、mips/mips64、powerpc/powerpc64、riscv32/riscv64 和 s390x 等，许多之前存在工具链问题、标准库支持缺失或崩溃的情况现在应该可以正常工作了。此外，该版本在构建系统方面进行了大量升级，并对语言进行了多项重要改进，例如引入了 Labeled Switch 和 Decl Literals 等新特性。为了缩短编辑/编译/调试周期，版本还迈向了两个长期投资目标：增量编译和快速 x86 后端。&lt;/p&gt;&lt;h3 id=&quot;target-support-tiers&quot;&gt;Zig 如何对不同目标平台的开发支持进行分级？&lt;/h3&gt;&lt;p&gt;Zig 使用四层系统来对不同目标平台的支持级别进行分类，其中 Tier 1 是最高级别：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Tier 1:&lt;/strong&gt; 所有非实验性语言特性都能正常工作。编译器能够独立生成目标平台的机器代码，功能与 LLVM 相当。即使在交叉编译时，该目标平台也有可用的 libc。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tier 2:&lt;/strong&gt; 标准库的跨平台抽象在该目标平台上有实现。该目标平台具备调试信息能力，可以在断言失败和崩溃时生成堆栈跟踪。CI 机器在每次 master 分支提交时都会自动构建和测试该目标平台。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tier 3:&lt;/strong&gt; 编译器可以依赖外部后端（如 LLVM）为该目标平台生成机器代码。链接器可以为该目标平台生成目标文件、库和可执行文件。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tier 4:&lt;/strong&gt; 编译器可以依赖外部后端（如 LLVM）为该目标平台生成汇编源代码。如果 LLVM 将此目标平台视为实验性，则需要从源代码构建 LLVM 和 Zig 才能使用它。&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;labeled-switch-advantages&quot;&gt;什么是 Labeled Switch，它有什么优势？&lt;/h3&gt;&lt;p&gt;Labeled Switch 是 Zig 0.14.0 中引入的一项语言特性，允许 switch 语句被标记，并作为 continue 语句的目标。continue :label value 语句会用 value 替换原始的 switch 表达式操作数，并重新评估 switch。尽管在语义上类似于循环中的 switch，但 Labeled Switch 的关键优势在于其代码生成特性。它可以生成帮助 CPU 更准确预测分支的代码，从而提高热循环中的性能，特别是在处理指令分派、评估有限状态自动机 (FSA) 或执行类似基于 case 的评估时。这有助于 branch predictor 更准确地预测控制流。&lt;/p&gt;&lt;h3 id=&quot;decl-literals-explanation&quot;&gt;Decl Literals 是什么，它解决了哪些问题？&lt;/h3&gt;&lt;p&gt;Decl Literals 是 Zig 0.14.0 扩展 “enum literal” 语法 (.foo) 而引入的新特性。现在，一个枚举字面量 .foo 不仅可以引用枚举变体，还可以使用 Result Location Semantics 引用目标类型上的任何声明（const/var/fn）。这在初始化结构体字段时特别有用，可以避免重复指定类型，并有助于避免 Faulty Default Field Values 的问题，确保数据不变量不会因覆盖单个字段而受到破坏。它也支持直接调用函数来初始化值。&lt;/p&gt;&lt;h3 id=&quot;allocator-changes&quot;&gt;Zig 0.14.0 版本在内存分配器方面有哪些值得关注的变化？&lt;/h3&gt;&lt;p&gt;该版本对内存分配器进行了多项改进：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;DebugAllocator:&lt;/strong&gt; GeneralPurposeAllocator 已被重写并更名为 DebugAllocator，以解决其依赖于编译时已知的页面大小的问题，并提升性能。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;SmpAllocator:&lt;/strong&gt; 引入了一个新的分配器，专为 ReleaseFast 优化模式和多线程环境设计。它是一个单例，使用全局状态，每个线程拥有独立的空闲列表，并通过原子操作处理线程资源回收，即使线程退出也能恢复数据。其性能与 glibc 相当。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Allocator API Changes (remap):&lt;/strong&gt; std.mem.Allocator.VTable 引入了一个新的 remap 函数，允许尝试扩展或收缩内存并可能重新定位，如果无法在不执行内部 memcpy 的情况下完成，则返回 null，提示调用者自行处理复制。同时，resize 函数保持不变。Allocator.VTable 中的所有函数现在使用 std.mem.Alignment 类型代替 u8，增加了类型安全。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Runtime Page Size:&lt;/strong&gt; 移除了编译时已知的 std.mem.page_size，代之以编译时已知的页面大小上下界 std.heap.page_size_min 和 std.heap.page_size_max。运行时获取页面大小可以使用 std.heap.pageSize()，它会优先使用编译时已知的值，否则在运行时查询操作系统并缓存结果。这修复了对 Asahi Linux 等新硬件上运行 Linux 的支持。&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;build-system-improvements&quot;&gt;Zig 0.14.0 版本如何改进构建系统，特别是处理模块和依赖关系？&lt;/h3&gt;&lt;p&gt;Zig 0.14.0 版本在构建系统方面有多项重要改进：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Creating Artifacts from Existing Modules:&lt;/strong&gt; 修改了构建系统 API，允许从现有的 std.Build.Module 对象创建 Compile 步骤。这使得模块图的定义更加清晰，并且可以更容易地重用图中的组件。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Allow Packages to Expose Arbitrary LazyPaths by Name:&lt;/strong&gt; 引入了 std.Build.Step.addNamedLazyPath 方法，允许包暴露命名的 LazyPath，例如生成的源代码文件，供依赖包使用。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;New Package Hash Format:&lt;/strong&gt; 引入了新的包哈希格式，包括 name、version 和 fingerprint 字段。fingerprint 是一个重要的概念，用于全局唯一标识包，即使在去中心化的生态系统中也能准确识别更新版本。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;addLibrary Function:&lt;/strong&gt; 引入 addLibrary 函数作为 addSharedLibrary 和 addStaticLibrary 的替代，允许在 build.zig 中更容易地切换链接模式，并与 linkLibrary 函数名称保持一致。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Import ZON:&lt;/strong&gt; ZON 文件现在可以在编译时通过 @import(“foo.zon”) 导入，前提是结果类型已知。&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;compiler-backend-and-speed&quot;&gt;Zig 0.14.0 版本在编译器后端和编译速度方面有哪些进展？&lt;/h3&gt;&lt;p&gt;该版本在编译器后端和编译速度方面取得了进展：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Multithreaded Backend Support:&lt;/strong&gt; 部分编译器后端，如 x86 Backend，现在支持在单独的线程中运行代码生成，这显著提高了编译速度。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Incremental Compilation:&lt;/strong&gt; 引入了增量编译特性，可以通过 -fincremental 标志启用。尽管尚未默认启用，但结合文件系统监听，可以显著缩短修改代码后的重新分析时间，提供快速的编译错误反馈。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;x86 Backend:&lt;/strong&gt; x86 后端在行为测试套件中的通过率已接近 LLVM 后端，并且在开发时通常比 LLVM 后端提供更快的编译速度和更好的调试器支持。虽然尚未默认选中，但鼓励用户尝试使用 -fno-llvm 或在构建脚本中设置 use_llvm = false 来启用。&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;toolchain-and-runtime-updates&quot;&gt;Zig 0.14.0 版本在工具链和运行时方面有哪些值得注意的更新？&lt;/h3&gt;&lt;p&gt;该版本在工具链和运行时方面也有多项更新：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;UBSan Runtime:&lt;/strong&gt; Zig 现在为 UBSan 提供了运行时库，在 Debug 模式下默认启用，可以在 C 代码触发未定义行为时提供详细的错误信息和堆栈跟踪。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;LLVM 19:&lt;/strong&gt; Zig 已升级到 LLVM 19.1.7 版本。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;musl 1.2.5:&lt;/strong&gt; 更新了捆绑的 musl 版本，并应用了安全补丁和目标平台特定补丁。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;glibc 2.41:&lt;/strong&gt; 支持 cross-compiling glibc 2.40 和 2.41 版本，并修复了多个问题，提高了与 glibc 的兼容性。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Linux 6.13.4 Headers:&lt;/strong&gt; 包含了 Linux 内核头文件版本 6.13.4。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Darwin libSystem 15.1:&lt;/strong&gt; 包含了 Xcode SDK 版本 15.1 的 Darwin libSystem 符号。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;MinGW-w64:&lt;/strong&gt; 更新了捆绑的 MinGW-w64 版本，并捆绑了 winpthreads 库，支持 cross-compiling 到 thumb-windows-gnu。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;wasi-libc:&lt;/strong&gt; 更新了捆绑的 wasi-libc 版本。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Optimized memcpy:&lt;/strong&gt; 提供了优化的 memcpy 实现，不再捆绑 musl 的 memcpy 文件。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Integrated Fuzzer:&lt;/strong&gt; 集成了 alpha 质量的 fuzzer，可以通过 –fuzz CLI 选项使用，并提供一个 fuzzer Web UI 显示实时代码覆盖率。&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;summary&quot;&gt;总结&lt;/h2&gt;&lt;p&gt;Zig 0.14.0 版本是向 1.0.0 版本迈进的重要一步，在性能优化（尤其是编译速度）、跨平台支持、语言特性和标准库方面都带来了显著改进。增量编译和快速 x86 后端是关键的长期投资，旨在提升开发者体验。新语言特性如 Labeled Switch 和 Decl Literals 提供了更强大和安全的编程模式。标准库的重组和容器的调整反映了社区的使用模式和最佳实践。构建系统也获得了重要升级，使模块管理和依赖处理更加灵活。尽管仍存在已知 bug，但 Zig 社区在本次发布中展示了活跃的开发和持续的进步。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/0.14/</link>
        <pubDate>Wed, 21 May 2025 01:26:22 +0000</pubDate>
        <guid>https://ziglang.cc/post/0.14/</guid>
      </item>
    
      <item>
        <title>Zig 的 comptime 太强了</title>
        <description>&lt;blockquote&gt;&lt;p&gt;原文：&lt;a href=&quot;https://www.scottredig.com/blog/bonkers_comptime/&quot; target=&quot;_blank&quot;&gt;https://www.scottredig.com/blog/bonkers_comptime/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;译注：原文中的代码块是交互式，翻译时并没有移植。另外，由于 comptime 本身即是关键概念，并且下文的意思更侧重于 Zig comptime 的特性，故下文大多使用 comptime 代替编译时概念。&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;introduction&quot;&gt;引言&lt;/h2&gt;&lt;p&gt;编程让数据处理自动化成为可能，大幅提升了生产力。而元编程更进一层——它让我们能像操作数据一样操作代码本身。在系统编程领域，元编程的潜力尤其大，因为高级抽象必须精确映射到硬件层面。不过我发现，除了函数式语言，大多数语言的元编程体验都不怎么样。所以当 Zig 把元编程作为核心特性时，我立刻来了兴趣。&lt;/p&gt;&lt;p&gt;刚开始用 Zig 的 comptime 时，体验挺糟糕的。概念陌生，想实现点什么都很费劲。但后来我找到了正确的理解方式，突然一切都通了，一下子就喜欢上了。为了让你少踩坑，下面我用六种不同”视角”来解释 comptime。每个视角都从不同角度切入，帮你把已有的编程经验迁移到 Zig。&lt;/p&gt;&lt;p&gt;这不是 comptime 的完整参考手册。相反，它提供多种思考策略，帮你建立以 comptime 为核心的思维方式。&lt;/p&gt;&lt;p&gt;为了清晰，所有示例都是有效的 Zig 代码，但其中的转换只是为了说明概念——并不是 Zig 实际的工作方式。&lt;/p&gt;&lt;h2 id=&quot;perspective-0-ignore-it&quot;&gt;视角 0：别管它&lt;/h2&gt;&lt;p&gt;我说我喜欢 comptime，转头又说可以忽略它，这听着有点矛盾。但我觉得这正是 Zig comptime 最厉害的地方。&lt;/p&gt;&lt;p&gt;Zig 哲学第三条说”倾向于阅读代码，而不是编写代码”。能轻松读懂代码在任何情况下都至关重要——这是理解概念、调试和修改的基础。&lt;/p&gt;&lt;p&gt;元编程很容易让人陷入”只写难读”的境地。用宏系统或代码生成器时，代码会有源码和展开后两个版本。这个额外间接层让阅读和调试都变难。你想改程序行为时，不仅要搞清楚生成的代码该长什么样，还得琢磨怎么通过元编程生成它们。&lt;/p&gt;&lt;p&gt;但在 Zig 里，这些开销都不需要。你可以直接忽略”代码在不同时间执行”这个隐藏前提，把编译时和运行时的区别当作透明层来理解。来看一个渐进式的例子。&lt;/p&gt;&lt;p&gt;先看普通的运行时代码：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;数组的和是 {d}。&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个很简单：求一组数的和。现在做点奇怪的——求结构体所有字段的和。虽然有点牵强，但它很好地展示思路。&lt;/p&gt;&lt;p&gt;再看一个真正基于 comptime 的实现：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fieldNames&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;结构体的和是 {d}。&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;跟数组求和的例子比，这个 comptime 版本只多了几个关键字。这正是 comptime 的精髓！&lt;/p&gt;&lt;p&gt;这段代码生成的机器码效率等同于你在 C 里手写一个求和函数，但它看起来像是在用支持运行时反射的语言编程。虽然这不是 Zig 实际的工作方式，但也不是纯理论：Zig 团队正在开发一个调试器，可以让你像这样一步步执行混合了编译时和运行时的代码。&lt;/p&gt;&lt;p&gt;Zig 有很多基于 comptime 的神奇操作，远不止简单的类型反射。关键是你可以直接阅读那些代码，完全不用理解背后 comptime 的细节。当然，如果你想写 comptime 代码，还是得深入了解。继续。&lt;/p&gt;&lt;h2 id=&quot;perspective-1-generics&quot;&gt;视角 1：泛型&lt;/h2&gt;&lt;p&gt;泛型在 Zig 里不是独立功能。恰恰相反，只用 comptime 的一小部分特性就足够实现所有泛型编程。这个视角虽然不能让你完全掌握 comptime，但它提供了一个切入点，让你能用元编程解决很多实际问题。&lt;/p&gt;&lt;p&gt;要让一个类型变成泛型，只需把它包在一个函数里——这个函数接受类型参数，返回类型。（译注：Zig 里类型是一等公民，所以”面向类型的编程”是完全合法的）&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;GenericMyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;sumFields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;GenericMyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fields&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fieldNames&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;GenericMyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;GenericMyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;结构体的和是 {d}。&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;sumFields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;泛型函数也是同样的道理：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;quadratic&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;quadratic&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;f32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number_float&quot;&gt;21.6&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number_float&quot;&gt;3.2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number_float&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;quadratic&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;结果：{d} 和 {d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当然，你也可以用特殊的 anytype 让编译器推断参数类型。这通常用在对函数签名其他部分没有影响的参数上。（译注：比如这里的 a、b、c、x 都要是同一种类型，所以直接指定 T 更合适）&lt;/p&gt;&lt;h2 id=&quot;perspective-2-standard-code-running-at-compile-time&quot;&gt;视角 2：在编译时运行普通代码&lt;/h2&gt;&lt;p&gt;这是个老故事了：想加个自动执行命令的功能？好，还得有变量。哦，再加条件判断。等等，循环呢？这些看似合理的需求最终把简单的宏系统搞成了怪物。但 Zig 不同——运行时、编译时甚至构建系统都用的是同一种语言。&lt;/p&gt;&lt;p&gt;来看经典的 Fizz Buzz 问题：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;AnyWriter&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;fizzbuzz&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;fizz&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;buzz&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;{d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;out_writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getStdOut&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;out_writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;确实很简单。但每次讨论 Fizz Buzz 优化时，人们总忘了这问题只需输出前 100 个数字的结果——既然输出是固定的，为什么不提前算好呢？（所以我觉得那些优化讨论有点小题大做）&lt;/p&gt;&lt;p&gt;我们可以用同一个 fizzBuzz 函数来实现预计算：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;full_fizzbuzz&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cw&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;countingWriter&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;null_writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cw&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;unreachable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cw&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;bytes_written&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fixedBufferStream&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;fizzBuzz&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;unreachable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;out_writer&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getStdOut&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;out_writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;full_fizzbuzz&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里 comptime 关键字表示它后面的代码块在编译期间运行。这个块被标记为”init”，以便通过 break 语句产出值。&lt;/p&gt;&lt;p&gt;我们先用一个 null_writer 来计算要写多少字节（但丢弃数据），然后根据这个长度创建正好大小的 buffer 来保存实际内容。&lt;/p&gt;&lt;p&gt;只计关键部分的执行时间，预计算版本大概快 9 倍。当然这个例子太简单了，总执行时间受很多因素影响，但你能从中感受到 comptime 对性能的意义。&lt;/p&gt;&lt;p&gt;comptime 和运行时之间有些小区别：比如只有 comptime 能访问 comptime_int、comptime_float 或 type 类型的变量；有些函数只接受 comptime 参数，只能在编译时使用。相反，只有运行时才能做系统调用和依赖系统调用的函数。如果你的代码不涉及这些，它在 comptime 和运行时表现完全一样。&lt;/p&gt;&lt;h2 id=&quot;perspective-3-partial-evaluation&quot;&gt;视角 3：程序特化&lt;/h2&gt;&lt;p&gt;&lt;em&gt;（Partial Evaluation 是一种编译优化技术：在编译期预先计算部分表达式或代码路径，减少运行时开销，生成更具体的版本）&lt;/em&gt;&lt;/p&gt;&lt;p&gt;现在进入更有趣的部分。&lt;/p&gt;&lt;p&gt;代码求值的一种思路是：把输入替换成它的运行时值，然后反复把第一个表达式替换成求值结果，直到表达式变成基本元素。这在函数式编程理论里很常见。接下来我用数组求和来展示这个过程：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 展开后相当于：&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;数组的和是 {d}。&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;程序特化可以接受函数的部分（但不一定是全部）参数。对于那些只使用已知值的表达式，直接替换成结果。这就产生了一个新函数，只接受仍然未知的参数。comptime 可以看作是在编译过程中进行的一部分求值。&lt;/p&gt;&lt;p&gt;再看结构体求和例子：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;sumFields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fieldNames&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 展开后相当于：&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 进一步简化：&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面这个展开过程是手动演示的，实际上是由 Zig 的 comptime 自动完成的。好处是你可以直接写出独立、完整的实现逻辑，不需要写”如果修改了 MyStruct 的字段，记得更新 sumFields”这种维护性注释。&lt;/p&gt;&lt;p&gt;基于 comptime 的版本会在 MyStruct 的任何字段变更时自动正确处理，这就是程序特化的思想。&lt;/p&gt;&lt;h2 id=&quot;perspective-4-comptime-evaluation-runtime-code-generation&quot;&gt;视角 4：comptime 求值与运行时代码生成&lt;/h2&gt;&lt;p&gt;这和程序特化很像。想象有两个版本的代码：编译前的（输入）和编译后的（输出）。输入代码由编译器运行。如果一个语句在编译时就能确定，它就会被直接求值掉；如果需要运行时值，这个语句就会被保留到输出代码里。&lt;/p&gt;&lt;p&gt;还是用结构体求和来演示这个过程：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 这段是输入代码（由编译器处理）：&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;sumFields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fieldNames&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 编译器生成的代码：&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;sumFields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这才是最接近 Zig 编译器处理 comptime 的方式。主要差别在于：Zig 首先把你的代码语法解析成虚拟机的字节码，然后运行这个虚拟机——这就是 comptime 的实现机制。这个虚拟机能评估任何它能处理的东西，并为需要运行时处理的部分生成新字节码（稍后转换成机器码）。有运行时输入的条件语句，比如 if，会直接输出两条分支。&lt;/p&gt;&lt;p&gt;这样做的副作用是：死代码永远不会被语义分析。也就是说，一个无效的函数不一定会在实际被使用时就报编译错误。（你可能需要适应这点）但这也让编译更高效，并且支持更自然的条件编译——这里没有 #ifdef 那种东西！&lt;/p&gt;&lt;p&gt;值得注意：comptime 在 Zig 的设计中非常底层，所有 Zig 代码（包括那些不明显使用 comptime 的）都会经过这个虚拟机。连简单的类型名（比如函数参数）都是在 comptime 中被评估的表达式。这就是前面泛型示例的工作原理。也正因如此，你可以用更复杂的表达式来计算类型。&lt;/p&gt;&lt;p&gt;另一个后果是：Zig 的静态分析比大多数静态类型语言复杂得多，因为编译器需要运行大量代码才能确定所有类型。所以，在工具链完善之前，IDE 的代码补全等功能可能不太稳定。&lt;/p&gt;&lt;h2 id=&quot;perspective-5-direct-code-generation&quot;&gt;视角 5：直接代码生成&lt;/h2&gt;&lt;p&gt;我在开头吐槽过元编程的难度。但即使在 Zig 里，元编程仍然是强大的工具，在某些场景下不可或缺。如果你熟悉其他语言的元编程方式，可能会觉得 Zig 的 comptime 功能有些残缺——比如，怎么在运行时生成新代码？&lt;/p&gt;&lt;p&gt;但等等，上一个例子不就是吗？只要换个角度看，“写代码的代码”和”混合编译时和运行时代码”之间其实是等价的。&lt;/p&gt;&lt;p&gt;看两个例子。第一个是元编程生成代码，第二个是我们熟悉的 comptime 版本。两段逻辑等价：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 元编程版本：代码生成器&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writeSumFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;AnyWriter&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;type_name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;field_names&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;fn sumFields(value: {s}) i64 {{&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;type_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;var sum: i64 = 0;&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_names&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;sum += value.{s};&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;return sum;&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;}}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 等价的 comptime 版本：&lt;/span&gt;
&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;sumFields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fieldNames&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;my_struct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意这里两次转换的分界线：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;在生成器里执行的代码属于 comptime&lt;/li&gt;&lt;li&gt;生成器输出后的代码属于运行时&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;我喜欢这个例子的另一个原因：它展示了用 Zig 把类型信息当输入来生成代码有多自然。这个例子没展示类型名和字段名从哪来。如果你用其他输入形式，Zig 有 @embedFile 完全可以直接读取和解析。&lt;/p&gt;&lt;p&gt;回到泛型例子，有个值得强调的微妙之处：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;writeMyStructOfType&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;AnyWriter&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;const MyStruct_{s} = struct {{&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;a: {s},&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;b: {s},&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;c: {s},&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;fn sumFields(value: MyStruct_{s}) {s} {{&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;var sum: {s} = 0;&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fields&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;c&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;sum += value.{s};&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;return sum;&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;}}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;}};&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个例子里结构体字段的生成同时体现了两种转换，而且混合在同一行里。字段的类型表达式是由生成器（运行时）完成的，而字段本身则是作为运行时代码使用的定义。&lt;/p&gt;&lt;p&gt;在 comptime 上下文中，引用类型名称的方式更直接：你直接用类型值就行，不需要像传统代码生成那样把文本拼成一个名字来保持一致。&lt;/p&gt;&lt;p&gt;有一种例外情况：你可以创建字段名在编译时就已经确定的类型，但这需要调用一个内置函数，它接受字段定义列表作为参数。所以你无法在这些类型上定义方法之类的声明。实践中这不会限制表达能力，但确实限制了你向其他代码公开的 API 种类。&lt;/p&gt;&lt;p&gt;说到文本宏——比如 C 那种——你大多数情况下都能在 comptime 里做到，尽管形式不太一样。但文本宏做不到的事，comptime 也做不到。比如你不能因为不喜欢某个 Zig 关键字就写个宏来代替它。我认为这是正确的决定，虽然对习惯了这个能力的人来说会难受一阵。再说，Zig 参考了半个世纪的编程语言设计经验，它的选择要理智得多。&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot;&gt;结语&lt;/h2&gt;&lt;p&gt;在读 Zig 代码来理解行为时，comptime 基本上不用考虑。而当我写 comptime 代码时，通常把它当作程序特化来用。不过，如果你知道用其他元编程方法怎么解决问题，你很可能能把它转化成 comptime 形式。&lt;/p&gt;&lt;p&gt;“直接代码生成”这种元编程方法的存在，正是我全力支持 Zig 这种 comptime 元编程的原因。直接生成代码几乎是功能最强大的元编程方式，但阅读和调试时”忽略 comptime”的方法又是最简单的。两者兼得，这就是《Zig 的 comptime 太强了》标题的由来。&lt;/p&gt;&lt;h2 id=&quot;further-reading&quot;&gt;延伸阅读&lt;/h2&gt;&lt;p&gt;Zig 不止 comptime 这一个亮点。去&lt;a href=&quot;https://ziglang.org/&quot; target=&quot;_blank&quot;&gt;官方网站&lt;/a&gt;可以了解更多。&lt;/p&gt;&lt;p&gt;本文多次用同一个例子展示不同转换来简化说明过程，这样做的缺点是：虽然说了很多，但实际没深入太多细节。&lt;a href=&quot;https://ziglang.org/documentation/0.13.0/&quot; target=&quot;_blank&quot;&gt;语言参考文档&lt;/a&gt;详细介绍了编译时的具体特性。&lt;/p&gt;&lt;p&gt;想看更多示例，我建议直接读 Zig 标准库代码。这里有几个跳转点：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ziglang/zig/blob/0.13.0/lib/std/fmt.zig#L80&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;std.debug.print&lt;/code&gt;&lt;/a&gt; 是个强大的泛型函数。很多语言在运行时解析格式字符串，还会加校验器来尽早抓错。而在 Zig 里，格式字符串在编译时解析，不仅生成了高效的最终代码，还在编译时完成所有校验。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/ziglang/zig/blob/0.13.0/lib/std/array_list.zig#L25&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;ArrayList&lt;/code&gt;&lt;/a&gt; 是一个实现简单但功能齐全的泛型容器。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Zig 的函数可以有多种返回类型。但这不靠什么编译器魔法，而是&lt;a href=&quot;https://github.com/ziglang/zig/blob/0.13.0/lib/std/start.zig#L508&quot; target=&quot;_blank&quot;&gt; comptime 的典型应用&lt;/a&gt;。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;如果你想对原文提出意见或更正，请发邮件至 &lt;a href=&quot;mailto:blogcomments@scottredig.com&quot; target=&quot;_blank&quot;&gt;blogcomments@scottredig.com&lt;/a&gt;。 译者注：如发现翻译问题，欢迎 PR 修改：&lt;a href=&quot;https://github.com/zigcc/zigcc.github.io&quot; target=&quot;_blank&quot;&gt;https://github.com/zigcc/zigcc.github.io&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;</description>
        <link>https://ziglang.cc/post/2025-01-23-bonkers-comptime/</link>
        <pubDate>Thu, 23 Jan 2025 04:00:00 +0000</pubDate>
        <guid>https://ziglang.cc/post/2025-01-23-bonkers-comptime/</guid>
      </item>
    
      <item>
        <title>在 zig 中实现类型安全的有限状态机</title>
        <description>&lt;h2 id=&quot;typed-fsm&quot;&gt;typed fsm&lt;/h2&gt;&lt;h2 id=&quot;1-briefly-introduce-the-advantages-of-typed-finite-state-machines&quot;&gt;1. 简单介绍类型化有限状态机的优势&lt;/h2&gt;&lt;h3 id=&quot;11-introduction-to-finite-state-machines&quot;&gt;1.1 介绍有限状态机&lt;/h3&gt;&lt;p&gt;有限状态机（FSM，以下简称状态机）是程序中很常见的设计模式。&lt;/p&gt;&lt;p&gt;它包含两个主要的概念状态和消息。状态机程序整体上的行为就是不断地产生消息，处理消息。&lt;/p&gt;&lt;p&gt;而状态主要是在代码层面帮助人们理解消息的产生和处理。&lt;/p&gt;&lt;h3 id=&quot;12-typed-fsm-zig&quot;&gt;1.2 typed-fsm-zig&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/sdzx-1/typed-fsm-zig&quot; target=&quot;_blank&quot;&gt;原文地址&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;typed-fsm-zig 是一个利用 zig 类型系统加一些编程规范实现的一个库，用于实现类型安全的有限状态机。&lt;/p&gt;&lt;p&gt;它具有以下两点优势：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;类型安全，极大方便代码的编写，修改和重构 手写状态机在实际代码中有很大的心智负担，对于它的修改和重构更是如噩梦一样。&lt;/p&gt;&lt;p&gt;typed-fsm-zig 在类型上跟踪状态机的变化，使消息的定义，产生，处理都和状态相关联，从而让类型系统帮我们检查这个过程中是否存在状态错误。&lt;/p&gt;&lt;p&gt;在编写，修改和重构的时候，任何状态的错误都会产生编译错误，而这些编译错误能帮助我们快速找到问题，解决问题。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;PS：推荐在 zls 中打开保存时检查，这样你几乎能得到一个交互式的状态机开发环境。&lt;/p&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;简单高效，无任何代码生成，能方便与现有逻辑整合&lt;/p&gt;&lt;p&gt;typed-fsm-zig 是一种编程的思想，掌握这种思想就能方便的使用它。&lt;/p&gt;&lt;p&gt;在实际的使用中没有任何的代码生成，除了一处隐式的约束要求之外，没有任何其它的控制，开发者完全掌握状态机，因此你可以方便的将它和你现有的代码结合起来。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;2-example-modifying-the-state-of-an-atm-state-machine&quot;&gt;2. 例子：修改 ATM 状态机的状态&lt;/h2&gt;&lt;p&gt;这里我将以一个 ATM 状态机（以下简称 ATM）的例子来展示 typed-fsm-zig 和 zig 的类型系统如何帮助我快速修改 ATM 的状态。&lt;/p&gt;&lt;p&gt;为了简单性，这里我不展示构建 ATM 这个例子的过程，感兴趣的可以在这里看到&lt;a href=&quot;https://github.com/sdzx-1/typed-fsm-zig/blob/master/examples/atm-gui.zig&quot; target=&quot;_blank&quot;&gt;代码&lt;/a&gt;。&lt;/p&gt;&lt;h3 id=&quot;21-introducing-atm-state-machines&quot;&gt;2.1 介绍 ATM 状态机&lt;/h3&gt;&lt;p&gt;ATM 代表自动取款机，因此它的代码的逻辑就是模拟自动取款机的一些行为：插入银行卡，输入 pin，检查 pin，取钱，修改 pin。&lt;/p&gt;&lt;p&gt;它的状态机整体如下：&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/typed-fsm/2.1-1.webp&quot;&gt;
&lt;figcaption&gt;ATM&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;图中椭圆形表示状态，箭头表示消息。 它包含五种状态：exit, ready, cardInserted, session, changePin。&lt;/p&gt;&lt;p&gt;同时它也包含一堆的消息，每个消息都包含了系统状态的转化。 比如消息 InsertCard 代表将 ATM 的状态从 ready 转化到 cardInserted，这代表用户插入卡。&lt;/p&gt;&lt;p&gt;消息 Incorrect 代表将 ATM 的状态从 cardInserted 转化到 cardInserted， 这代表了一种循环，表示用户输错了 pin，但是可以再次尝试输入 pin，当然我们要求最多可以尝试三次。&lt;/p&gt;&lt;p&gt;整个程序效果如下：&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/typed-fsm/2.1-2.webp&quot;&gt;
&lt;figcaption&gt;ATM&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;这里注意消息 Update，它代表更新 pin，同时将状态转从 changePin 换到 ready。&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/typed-fsm/2.1-4.webp&quot;&gt;
&lt;figcaption&gt;ATM&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;实际的表现就是在 changePin 的界面中我们修改 pin，然后点击 Change 按钮触发 Update 消息，修改 pin，并返回到 ready 界面。&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/typed-fsm/2.1-3.webp&quot;&gt;
&lt;figcaption&gt;ATM&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;接下来的文章中我将修改 Update 的行为，并展示在这个过程中类型系统如何帮助我快速调整代码。&lt;/p&gt;&lt;h3 id=&quot;22-modify-update-messages&quot;&gt;2.2 修改 Update 消息&lt;/h3&gt;&lt;p&gt;实际的消息 Update 定义代码如下&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;changePinMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;AtmSt&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Update&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;WitFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的.ready 就代表了处理完 Update 消息后就会进入 ready 状态。&lt;/p&gt;&lt;p&gt;我们修改这里，把它变成.cardInserted，这代表了我们要求更新完 pin 之后进入 cardInserted 界面重新输入新的 pin，这看着是个合理的要求。&lt;/p&gt;&lt;p&gt;新的状态图如下：&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/typed-fsm/2.2-1.webp&quot;&gt;
&lt;figcaption&gt;ATM&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;这时如果我重新编译代码，那么类型系统就会产生下面的错误：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;
&lt;span class=&quot;constant function&quot;&gt;➜&lt;/span&gt;  &lt;span class=&quot;constant&quot;&gt;typed-fsm-zig&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;git:&lt;/span&gt;(&lt;span class=&quot;constant function&quot;&gt;doc&lt;/span&gt;) &lt;span class=&quot;constant function&quot;&gt;✗&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;atm-gui&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;atm-gui&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;└─&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;atm-gui&lt;/span&gt;
   &lt;span class=&quot;constant function&quot;&gt;└─&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build-exe&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;atm-gui&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Debug&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;native&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;errors&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;examples/atm-gui.zig:301:60:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;error:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;expected&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;typed-fsm.Witness(atm-gui.AtmSt,.exit,.ready)&amp;apos;&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;found&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;typed-fsm.Witness(atm-gui.AtmSt,.exit,.cardInserted)&amp;apos;&lt;/span&gt;
                    &lt;span class=&quot;constant function&quot;&gt;@call&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;.always_tail,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;readyHandler,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;.{&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;val.wit,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;ist&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;}&lt;/span&gt;);
                                                        &lt;span class=&quot;constant function&quot;&gt;~~~^~~~&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;src/typed-fsm.zig:9:20:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;note:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;declared&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;here&lt;/span&gt; (&lt;span class=&quot;constant function&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;times&lt;/span&gt;)
            &lt;span class=&quot;constant function&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;{&lt;/span&gt;
                   &lt;span class=&quot;constant function&quot;&gt;^~~~~~&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;examples/atm-gui.zig:254:46:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;note:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;parameter&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;declared&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;here&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;readyHandler(comptime&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;w:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;AtmSt.EWitness&lt;/span&gt;(&lt;span class=&quot;constant function&quot;&gt;.ready&lt;/span&gt;), &lt;span class=&quot;constant function&quot;&gt;ist:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;*InternalState&lt;/span&gt;) &lt;span class=&quot;constant&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;{&lt;/span&gt;
                               &lt;span class=&quot;constant function&quot;&gt;~~~~~~~~~~~~~~^~~~~~~~&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;referenced&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;by:&lt;/span&gt;
    &lt;span class=&quot;constant function&quot;&gt;cardInsertedHander__anon_6916:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;examples/atm-gui.zig:271:13&lt;/span&gt;
    &lt;span class=&quot;constant function&quot;&gt;readyHander__anon_3925:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;examples/atm-gui.zig:261:13&lt;/span&gt;
    &lt;span class=&quot;constant function&quot;&gt;5&lt;/span&gt; reference&lt;span class=&quot;constant&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;s&lt;/span&gt;) hidden; &lt;span class=&quot;constant function&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;-freference-trace=7&amp;apos;&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;see&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;references&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它告诉我们在 301 行存在类型不匹配。因为之前的状态是 ready 所以使用 readyHandler。&lt;/p&gt;&lt;p&gt;当我们把 Update 的状态修改为 cardInserted 时，它与 readyHandler 类型不匹配，应该将它修改为 cardInsertedHandler。&lt;/p&gt;&lt;p&gt;修改之后的代码如下：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;function_builtin&quot;&gt;@call&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;always_tail&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cardInsertedHandler&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ist&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这里类型系统精确的告诉了我们需要修改的地方，以及原因。修改完成后程序即能正确运行。&lt;/p&gt;&lt;h3 id=&quot;23-remove-changepin-status&quot;&gt;2.3 移除 changePin 状态&lt;/h3&gt;&lt;p&gt;这一节中我们尝试移除 changePin 状态，看看类型系统会给我们什么反馈。 如果移除 changePin，新的状态图如下：&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/typed-fsm/2.3-1.webp&quot;&gt;
&lt;figcaption&gt;ATM&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;重新编译项目，将获得类型系统的反馈&lt;/p&gt;&lt;p&gt;类型系统的反馈首先是：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;examples/atm-gui.zig:148:36:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;error:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;atm-gui.AtmSt&amp;apos;&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;member&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;named&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;changePin&amp;apos;&lt;/span&gt;
            &lt;span class=&quot;constant function&quot;&gt;ChangePin:&lt;/span&gt; WitFn&lt;span class=&quot;constant&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;end,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;.changePin&lt;/span&gt;),
                                  ~^~~~~~~~~
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为 changePin 状态已经被移除，因此消息 ChangePin（它代表了从 session 进入 changePin 状态）也不应该再存在了，我们移除它再重新编译。&lt;/p&gt;&lt;p&gt;新的反馈如下：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;examples/atm-gui.zig:161:64:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;error:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;atm-gui.AtmSt.sessionMsg(.exit)&amp;apos;&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;member&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;named&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;ChangePin&amp;apos;&lt;/span&gt;
                    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;constant function&quot;&gt;resource.changePin.toButton&lt;/span&gt;()) &lt;span class=&quot;constant&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;.ChangePin&lt;/span&gt;;
                                                              &lt;span class=&quot;constant function&quot;&gt;~^~~~~~~~~&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们移除 ChangePin 消息，因此也将它从消息产生的地方移除，继续重新编译。&lt;/p&gt;&lt;p&gt;新的反馈如下：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;examples/atm-gui.zig:296:10:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;error:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;no&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;field&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;named&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;ChangePin&amp;apos;&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;string constant&quot;&gt;&amp;apos;@typeInfo(atm-gui.AtmSt.sessionMsg(.exit)).@&amp;quot;union&amp;quot;.tag_type.?&amp;apos;&lt;/span&gt;
        &lt;span class=&quot;constant function&quot;&gt;.ChangePin&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; {
        &lt;span class=&quot;constant function&quot;&gt;~^~~~~~~~~&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为消息 ChangePin 已经不在了，也应将它从消息处理的地方移除，继续重新编译。&lt;/p&gt;&lt;p&gt;这一次不再有编译错误产生，我们搞定了一个新的程序，它不再包含 changePin 的逻辑。&lt;/p&gt;&lt;p&gt;在这个过程中类型系统帮助我们找到问题和原因。这非常酷！！！&lt;/p&gt;&lt;h3 id=&quot;24-summary&quot;&gt;2.4 总结&lt;/h3&gt;&lt;p&gt;以上是一个简单的例子，展示了 typed-fsm-zig 对于提升状态机编程体验的巨大效果。&lt;/p&gt;&lt;p&gt;展示类型系统如何帮助我们指示错误的地方，把复杂的状态机修改变成一种愉快的编程经历。&lt;/p&gt;&lt;p&gt;还有些没有讲到的优势如下：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;状态的分离，后端 handler 处理业务的状态变化，前端渲染和消息生成不改变状态。&lt;/li&gt;&lt;li&gt;消息生成受到类型的限制和状态相关，这样避免错误消息的产生。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;这些优势对于复杂业务有很大的帮助。&lt;/p&gt;&lt;p&gt;接下来我将介绍 typed-fsm-zig 的原理和实现。&lt;/p&gt;&lt;h2 id=&quot;3-principle-and-implementation&quot;&gt;3. 原理与实现&lt;/h2&gt;&lt;p&gt;最开始的版本是&lt;a href=&quot;https://github.com/sdzx-1/typed-fsm&quot; target=&quot;_blank&quot;&gt;typed-fsm&lt;/a&gt;，由使用 haskell 实现，它实现了完整类型安全的有限状态机。&lt;/p&gt;&lt;p&gt;typed-fsm 基于&lt;a href=&quot;https://hackage.haskell.org/package/typed-fsm-0.3.0.1/docs/Data-IFunctor.html&quot; target=&quot;_blank&quot;&gt;Mcbride Indexed Monad&lt;/a&gt;：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;haskell&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;boolean keyword_exception keyword_debug type variable function_call&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;~&amp;gt;&lt;/span&gt; &lt;span class=&quot;boolean keyword_exception keyword_debug type variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;forall&lt;/span&gt; &lt;span class=&quot;boolean keyword_exception keyword_debug type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;boolean keyword_exception keyword_debug type variable&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;boolean keyword_exception keyword_debug type variable&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;boolean keyword_exception keyword_debug type variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;boolean keyword_exception keyword_debug type variable&quot;&gt;i&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;IMonad&lt;/span&gt; &lt;span class=&quot;boolean keyword_exception keyword_debug type variable&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;where&lt;/span&gt;
  &lt;span class=&quot;variable function boolean keyword_exception keyword_debug type&quot;&gt;ireturn&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;variable boolean keyword_exception keyword_debug type function_call&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;~&amp;gt;&lt;/span&gt; &lt;span class=&quot;variable boolean keyword_exception keyword_debug type&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;variable boolean keyword_exception keyword_debug type&quot;&gt;a&lt;/span&gt;
  &lt;span class=&quot;variable function boolean keyword_exception keyword_debug type&quot;&gt;ibind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable boolean keyword_exception keyword_debug type function_call&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;~&amp;gt;&lt;/span&gt; &lt;span class=&quot;variable boolean keyword_exception keyword_debug type&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;variable boolean keyword_exception keyword_debug type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;variable boolean keyword_exception keyword_debug type&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;variable boolean keyword_exception keyword_debug type&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;~&amp;gt;&lt;/span&gt; &lt;span class=&quot;variable boolean keyword_exception keyword_debug type&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;variable boolean keyword_exception keyword_debug type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是一种特殊的 monad，能在类型上为不确定状态建模。&lt;/p&gt;&lt;p&gt;而在 zig 实现中移除了对 Monad 语义的需求，保留了在类型上追踪状态的能力。&lt;/p&gt;&lt;p&gt;所以它不具备完整的类型安全的能力，需要依靠编程规范来约束代码的行为。我认为这样的取舍是值得的，它的类型安全性在 zig 中完全够用。&lt;/p&gt;&lt;p&gt;以下是一个原型例子，它包含了 typed-fsm-zig 的核心想法。看不懂不需要担心，接下来我将详细解释这些代码。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1Wit&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1Wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;STM&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@compileError&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Can&amp;apos;t getMsg!&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;STM&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;terminal&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@compileError&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Can&amp;apos;t terminal!&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// State to Message union&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;STM&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;exitMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s2Msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;exitMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s1Msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;S1ToS2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S1ToS2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s2Msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;S2ToS1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S2ToS1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;val: {d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;terminal&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S1ToS2&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s2Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s2Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S2ToS1&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;首先是 Witness，它是一个类型上的证据，用来跟踪类型上状态的变化。&lt;/p&gt;&lt;p&gt;这里有一些介绍 Witness 思想的&lt;a href=&quot;https://wiki.haskell.org/Type_witness&quot; target=&quot;_blank&quot;&gt;文章 1&lt;/a&gt;,&lt;a href=&quot;https://serokell.io/blog/haskell-type-level-witness&quot; target=&quot;_blank&quot;&gt;文章 2&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;感兴趣的可以看一下，看懂这些要求你了解 GADT，上面提到的 Mcbirde Indexed Monad 本质就是在 GADT 类型上的 monad。&lt;/p&gt;&lt;p&gt;在这里的 Winess 三个参数分别表示：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;T 表示状态机的类型，&lt;/li&gt;&lt;li&gt;end 表示终止时的状态，&lt;/li&gt;&lt;li&gt;start 表示当前的状态。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;它还有两个函数：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;getMsg 表示从外部获取消息的函数&lt;/li&gt;&lt;li&gt;terminal 表示终止状态机的函数。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;当 end == start 时表示当前处于终止状态，因此 Witness 只能使用 terminal 函数，当 end != start 时表示当前不处于终止状态，应该继续从外部获取消息，因此 Witness 只能使用 getMsg 函数。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;STM&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@compileError&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Can&amp;apos;t getMsg!&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;STM&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;terminal&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@compileError&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Can&amp;apos;t terminal!&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们在这里定义状态。Example 包含三个状态：exit，s1，s2。我们将在类型上跟踪这些状态的变化。&lt;/p&gt;&lt;p&gt;注意这里的 STM 函数，它代表如何将状态映射到对应的消息集合。在实际 typed-fsm-zig 的代码中，这就是我所说的那一处隐式的约束要求。&lt;/p&gt;&lt;p&gt;实际代码中会将消息集合整合在 enum 的内部，使用特殊的命名规范将状态与消息集合对应。目前的隐式规范是在状态后面加上 Msg。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// State to Message union&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;STM&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;exitMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s2Msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下来是消息的定义和产生，&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// exit 状态下没有任何消息&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;exitMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// s1 状态下有两个消息 Exit 和 S1ToS2, 他们分别将状态转化为 exit 和 s2&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s1Msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;S1ToS2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// getMsg 函数表明在 s1 状态下如何产生消息，这里受到类型系统的约束，&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 在 s1 的状态下不会产生其它状态的消息&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S1ToS2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// s2 状态下有一个消息 S2ToS1&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s2Msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;S2ToS1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S2ToS1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后一部分是消息的处理。&lt;/p&gt;&lt;p&gt;整体的逻辑是通过 Witness 的 getMsg 函数从外部获取消息，然后通过模式匹配处理消息。 每个消息又包含接下来状态的 Witness，然后使用对应的函数处理这些 Witness。&lt;/p&gt;&lt;p&gt;通过 Witness 让类型系统帮我们检查函数的调用是否正确。&lt;/p&gt;&lt;p&gt;通过对消息进行模式匹配，编译器能确定我们是否正确且完整的处理了所有的消息。&lt;/p&gt;&lt;p&gt;这些对于代码的编写，修改，重构都有巨大的帮助。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;val: {d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;terminal&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S1Tos2&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s2Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s2Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S2Tos1&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上就是 typed-fsm-zig 核心想法的完整介绍。接下来我将介绍需要的编程规范。&lt;/p&gt;&lt;h2 id=&quot;4-what-programming-specifications-do-typed-fsm-zig-need&quot;&gt;4. typed-fsm-zig 需要哪些编程规范&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;状态和消息集合之间需要满足的隐式命名规范&lt;/p&gt;&lt;p&gt;以 ATM 为例：&lt;/p&gt;&lt;p&gt;exit – exitMsg&lt;/p&gt;&lt;p&gt;ready – readyMsg&lt;/p&gt;&lt;p&gt;cardInserted – cardInsertedMsg&lt;/p&gt;&lt;p&gt;session – sessionMsg&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;AtmSt&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cardInserted&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;exitMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;AtmSt&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;readyMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;AtmSt&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ExitAtm&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;WitFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;InsertCard&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;WitFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cardInserted&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;genMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;cardInsertedMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;AtmSt&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Correct&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;WitFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Incorrect&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;WitFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cardInserted&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;EjectCard&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;WitFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;genMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ist&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InternalState&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                 &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;sessionMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;AtmSt&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Disponse&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;WitFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;EjectCard&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;WitFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;genMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ist&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InternalState&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;&lt;li&gt;&lt;p&gt;除了 exit 状态外，其它消息需要包含 genMsg 函数用于产生消息，任何消息都必须带有 Witness&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;状态机都需要定义退出状态，尽管你可能永远也不会退出状态机，但退出状态作用于类型上，是不可缺少的&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;在互相调用其它 handler 的时候使用尾递归的语法，并且在必须在语句块最后处理消息附带的 Witness&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;由于 zig 的实现缺少 Mcbride Indexed Monad 语义的支持，因此类型系统不能阻止你进行下面的操作：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 使用上面 Example 的处理函数 s1Handler, 将它修改成下面的样子。&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 这里的 s1Handler 不应该被多次调用，在 haskell 版本的 typed-fsm 中，类型系统能检查出这里类型错误，但是在 zig 实现中无法做到，&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 因此我们要求只能在语句块最后有一个处理 Witness 的语句&lt;/span&gt;
&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;s2Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Exmaple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;S2Tos1&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;s1Handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wit&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;由于状态机需要长期运行，在互调递归的函数中如果不使用尾递归会导致栈溢出。&lt;/p&gt;&lt;p&gt;因此上面的 Example demo 中，如果我将 20 改成很大的值，比如二百万，那么一定会发生栈溢出，因为 demo 中的调用没采用尾递归的方式。&lt;/p&gt;&lt;p&gt;在实际的 ATM 例子中他们的调用方式是：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;readyHandler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;AtmSt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;EWitness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ist&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InternalState&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getMsg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExitAtm&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;witness&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;terminal&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InsertCard&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;witness&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ist&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;times&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;function_builtin&quot;&gt;@call&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;always_tail&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cardInsertedHandler&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;witness&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ist&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的 &lt;code&gt;@call(.always_tail, cardInsertedHandler, .{ witness, ist })&lt;/code&gt; 就是 zig 中尾递归语法（参见：&lt;a href=&quot;https://github.com/ziglang/zig/issues/694#issuecomment-563310662&quot; target=&quot;_blank&quot;&gt;ziglang #694&lt;/a&gt;）。出于这个语法的需要，处理函数中的 Witness 被变成了编译时已知（这里是 &lt;code&gt;comptime w: AtmSt.EWitness(.ready)&lt;/code&gt;）。&lt;/p&gt;&lt;p&gt;遵循这四点要求，就能获得强大的类型安全保证，足以让你愉快的使用状态机！&lt;/p&gt;&lt;h2 id=&quot;5-future-enhancements&quot;&gt;5. 接下来能够增强的功能&lt;/h2&gt;&lt;p&gt;暂时我能想到的有如下几点：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;在状态机中，消息的产生和处理分开，因此可以定义多个消息产生的前端，处理部分可以任意切换消息产生的前端。比如我们可以定义测试状态机前端，用于产生测试数据，当处理部分调用测试前端的代码时就能测试整个状态机的行为。&lt;/li&gt;&lt;li&gt;支持子状态，这会让类型更加复杂。&lt;/li&gt;&lt;li&gt;开发基于&lt;a href=&quot;https://discourse.haskell.org/t/try-to-combine-typed-fsm-with-gui-to-produce-unexpected-abstract-combinations/10026&quot; target=&quot;_blank&quot;&gt;typed-fsm-zig 的 gui 系统&lt;/a&gt;，状态机在 gui 有很高的实用性，将他们结合是一个不错的选择。&lt;/li&gt;&lt;li&gt;开发 typed-session-zig，实现类型安全的通信协议。我在 haskell 已经实现了一个&lt;a href=&quot;https://github.com/sdzx-1/typed-session&quot; target=&quot;_blank&quot;&gt;实用的类型安全的多角色通讯协议框架&lt;/a&gt;，应该可以移植到 zig 中。&lt;/li&gt;&lt;/ol&gt;</description>
        <link>https://ziglang.cc/post/2024-11-26-typed-fsm/</link>
        <pubDate>Tue, 26 Nov 2024 05:32:00 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-11-26-typed-fsm/</guid>
      </item>
    
      <item>
        <title>zoop 实现原理分析</title>
        <description>&lt;h2 id=&quot;zoop&quot;&gt;zoop&lt;/h2&gt;&lt;p&gt;zoop 是 zig 的一个 OOP 解决方案，详细信息可以看看 &lt;a href=&quot;https://zhuyadong.github.io/zoop-docs/&quot; target=&quot;_blank&quot;&gt;zoop 官网&lt;/a&gt;。&lt;/p&gt;&lt;h2 id=&quot;why-not-use-another-oop-language&quot;&gt;为什么不用别的 OOP 语言&lt;/h2&gt;&lt;p&gt;简单的说，是我个人原因，必需使用 zig 的同时，还一定要用 OOP，所以有了 zoop。&lt;/p&gt;&lt;h2 id=&quot;getting-started-with-zoop&quot;&gt;zoop 入门&lt;/h2&gt;&lt;h3 id=&quot;classes-and-methods&quot;&gt;类和方法&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Mixin&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2-3 行是一个 struct 成为 zoop 类必需的两行，这样一来，&lt;code&gt;Base&lt;/code&gt; 就成为了一个 zoop 的类。&lt;/p&gt;&lt;p&gt;创建 &lt;code&gt;Base&lt;/code&gt; 的对象有两种方法：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;在堆上： &lt;code&gt;var obj = try Base.new(allocator);&lt;/code&gt;&lt;/li&gt;&lt;li&gt;在栈上：&lt;code&gt;var obj = Base.make(); obj.initMixin();&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;栈上创建的对象必需调用对象的 &lt;code&gt;initMixin()&lt;/code&gt; 方法，因为对象地址对 zoop 来说很重要，而在 &lt;code&gt;make()&lt;/code&gt; 中是无法知道这个返回的对象会放在什么地址，只能通过外部调用 &lt;code&gt;initMixin()&lt;/code&gt; 来通知 zoop 这个地址。&lt;/p&gt;&lt;p&gt;销毁对象的方法是 &lt;code&gt;obj.destroy()&lt;/code&gt;，这是 zoop 自动为所有类加上的方法，不需要用户去定义。&lt;/p&gt;&lt;p&gt;我们可以给 &lt;code&gt;Base&lt;/code&gt; 加上方法和字段，就是正常的 zig 方法和字段：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Mixin&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为创建 zoop 类对象的方法不是 &lt;code&gt;init()&lt;/code&gt;，因此在 zoop 类中，一般把 &lt;code&gt;init()&lt;/code&gt; 当作初始化方法而不是创建方法。这种常规的方法，是没法被子类继承的，属于类的私有方法。要定义可以继承的方法，需要用如下形式来定义：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 和上面一样，这里不写了&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Method&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看起来有点怪，下面解释 zoop 实现原理的时候会解释这些奇怪的地方，现在我们先熟悉用法，不要在意这些细节^_^。&lt;/p&gt;&lt;p&gt;上面的代码给 &lt;code&gt;Base&lt;/code&gt; 添加了一个可以继承的方法 &lt;code&gt;getName()&lt;/code&gt;。&lt;/p&gt;&lt;h3 id=&quot;class-inheritance&quot;&gt;类的继承&lt;/h3&gt;&lt;p&gt;zoop 引入一个关键字 &lt;code&gt;extends&lt;/code&gt; 用来实现继承，比如下面我们定义 &lt;code&gt;Base&lt;/code&gt; 的子类 &lt;code&gt;Child&lt;/code&gt;：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Child&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 表示我继承 Base&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必要的两行&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Mixin&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 我的初始化函数，里面调用父类的初始化函数&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Child&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Child&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;sub&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 使用继承来的方法 getName()&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;expectEqualStrings&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;sub&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;interface-definition&quot;&gt;接口定义&lt;/h3&gt;&lt;p&gt;zoop 中的接口，实际上是一个胖指针。下面我们定义一个接口 &lt;code&gt;IGetName&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IGetName&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 定义接口的 `Vtable`，说明接口有哪些方法&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Vtable&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;DevVtable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必需的一行&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必需的两个字段&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Vtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必需的胶水代码，用来调用 `Vtable` 里面的函数&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的代码具体原理下面会说到，这里大家知道接口就是这样定义的就行了。上面的代码定义了接口 &lt;code&gt;IGetName&lt;/code&gt;，这个接口有一个方法 &lt;code&gt;getName()&lt;/code&gt;。&lt;/p&gt;&lt;h3 id=&quot;interface-implementation&quot;&gt;接口实现&lt;/h3&gt;&lt;p&gt;上面的 &lt;code&gt;Base&lt;/code&gt; 类正好也有个符合 &lt;code&gt;IGetName&lt;/code&gt; 接口的方法 &lt;code&gt;getName()&lt;/code&gt;，那我们修改一下 &lt;code&gt;Base&lt;/code&gt; 的代码让它来实现 &lt;code&gt;IGetName&lt;/code&gt; 接口：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 我实现 IGetName 接口&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IGetName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 以下省略&lt;/span&gt;
    &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看到实现接口和继承用的同样一个关键字 &lt;code&gt;extends&lt;/code&gt;。因为子类会继承父类的接口，所以这样一来，&lt;code&gt;Child&lt;/code&gt; 也自动实现了 &lt;code&gt;IGetName&lt;/code&gt; 接口。&lt;/p&gt;&lt;h3 id=&quot;method-overrides-and-virtual-function-calls&quot;&gt;方法重写和虚函数调用&lt;/h3&gt;&lt;p&gt;我们修改上面 &lt;code&gt;Child&lt;/code&gt; 的代码，重写 &lt;code&gt;getName()&lt;/code&gt; 方法：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Child&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 省略上面已知代码，下面代码重写了 Base.getName()&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Method&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;override&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;要注意，只有可继承方法才可以被重写，可继承方法和重写的方法都要通过上面 &lt;code&gt;pub fn Fn(comptime T: type) type&lt;/code&gt; 这样的方式来定义。 重写的方法，只有通过接口，才能进行虚函数调用，下面是例子：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Child&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Child&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; child&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 不通过接口调用 getName()&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;expectEqualStrings&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;override&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; t&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;expectEqualStrings&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Child&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 通过接口调用 (虚函数调用) getName();&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;expectEqualStrings&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IGetName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;override&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; t&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;expectEqualStrings&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IGetName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;override&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面例子中 &lt;code&gt;cast&lt;/code&gt;、&lt;code&gt;as&lt;/code&gt; 属于 zoop 中的类型转换，详细可以参考 &lt;a href=&quot;https://zhuyadong.github.io/zoop-docs/guide/as-cast&quot; target=&quot;_blank&quot;&gt;zoop 类型转换&lt;/a&gt;&lt;/p&gt;&lt;p&gt;那么 zoop 的基本使用方法就介绍到这里，下面我们开始介绍 zoop 的实现原理。&lt;/p&gt;&lt;h2 id=&quot;preset-scene&quot;&gt;预设场景&lt;/h2&gt;&lt;p&gt;接下来的讨论基于如下的属于 &lt;code&gt;mymod&lt;/code&gt; 模块的类和接口：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;/// 接口 IGetName&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IGetName&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Vtable&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;DevVtable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Vtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;/// 接口 ISetName&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ISetName&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Vtable&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;DevVtable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Vtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Api&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;/// 基类 Base&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ISetName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Mixin&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Method&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;/// 子类 Child&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Child&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IGetName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Mixin&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Method&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接口有两个：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;IGetName&lt;/code&gt;: 接口方法 &lt;code&gt;getName&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;ISetName&lt;/code&gt;: 接口方法 &lt;code&gt;setName&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;类有两个：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;Base&lt;/code&gt;: 基类，实现接口 &lt;code&gt;ISetName&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;Child&lt;/code&gt;: 子类，继承 &lt;code&gt;Base&lt;/code&gt;，并实现接口 &lt;code&gt;IGetName&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;core-data-structure-zoopmixint&quot;&gt;核心数据结构 &lt;code&gt;zoop.Mixin(T)&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;我们看看两个类的 &lt;code&gt;mixin&lt;/code&gt; 这个数据里面有什么：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;VtableFunc&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ifacename&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IObject&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Vtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SuperPtrFunc&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;rootptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Mixin&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;deallocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;rootptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getVtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;VtableFunc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getSuperPtr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SuperPtrFunc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

zoop&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Mixin&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Child&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;deallocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;rootptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;typeinfo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;typename&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getVtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;VtableFunc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;getSuperPtr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SuperPtrFunc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mymod_Base&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看出，两者的唯一的差别在于 &lt;code&gt;Child.mixin.data&lt;/code&gt; 里面包含了一个 &lt;code&gt;Base&lt;/code&gt;, 而 &lt;code&gt;Base.mixin.data&lt;/code&gt; 里面是空的。说明在 zoop 中，类有多少个父类，则类的 &lt;code&gt;mixin.data&lt;/code&gt; 中，就有多少个父类的数据。&lt;/p&gt;&lt;p&gt;我们再来看看 &lt;code&gt;mixin.meta&lt;/code&gt; 这个数据。先看看 &lt;code&gt;rootptr&lt;/code&gt; 这个字段，如果我们现在有一个 &lt;code&gt;Base&lt;/code&gt; 对象 &lt;code&gt;base&lt;/code&gt;，那么 &lt;code&gt;base.mixin.meta.rootptr == &amp;amp;base&lt;/code&gt; 是成立的；如果现在有一个 &lt;code&gt;Child&lt;/code&gt; 对象 &lt;code&gt;child&lt;/code&gt;，那么如下两条成立：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;child.mixin.meta.rootptr == &amp;amp;child&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;child.mixin.data.mymod_Base.mixin.meta.rootptr == &amp;amp;child&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;事实上，&lt;code&gt;child.mixin.data.mymod_Base.mixin.meta&lt;/code&gt; 里面的内容就是完全复制的 &lt;code&gt;child.mixin.meta&lt;/code&gt;，因为所有内层对象的 &lt;code&gt;mixin.meta&lt;/code&gt; 都是复制的最外层那个对象的 &lt;code&gt;mixin.meta&lt;/code&gt;，因而所有对象的 &lt;code&gt;rootptr&lt;/code&gt; 都指向最外层对象，这也是为什么叫 &lt;code&gt;rootptr&lt;/code&gt; 的原因。&lt;/p&gt;&lt;p&gt;再看看 &lt;code&gt;typeinfo&lt;/code&gt; 字段，这个字段是一个有 3 个字段的结构：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;typename&lt;/code&gt;: 这是 &lt;code&gt;rootptr&lt;/code&gt; 指向对象的类型名&lt;/li&gt;&lt;li&gt;&lt;code&gt;getVtable&lt;/code&gt;: 根据接口名获得接口 &lt;code&gt;Vtable&lt;/code&gt; 的函数&lt;/li&gt;&lt;li&gt;&lt;code&gt;getSuperPtr&lt;/code&gt;: 根据父类名获得 &lt;code&gt;mixin.data&lt;/code&gt; 中父类指针&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;上面两个函数获取的都是最外层对象的数据。根据对 &lt;code&gt;mixin&lt;/code&gt; 数据的分析，zoop 的类型转换的原理就很清楚了，大家可以参考官网上关于 &lt;a href=&quot;https://zhuyadong.github.io/zoop-docs/guide/as-cast&quot; target=&quot;_blank&quot;&gt;类型转换&lt;/a&gt; 的内容。&lt;/p&gt;&lt;h2 id=&quot;dynamically-constructing-class-methods-interface-methods-and-vtable&quot;&gt;动态构造类的方法、接口方法、和 &lt;code&gt;Vtable&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;OOP 概念中的继承，重写，虚函数，实质其实就是在编译时动态构造需要的方法和属性。zoop 中主要是通过通过 &lt;a href=&quot;https://zhuyadong.github.io/zoop-docs/reference/tuple&quot; target=&quot;_blank&quot;&gt;zoop.tuple&lt;/a&gt; 这个模块来进行编译时动态构造。&lt;/p&gt;&lt;p&gt;这部分需要大家有一定的 &lt;a href=&quot;https://ziglang.org/documentation/0.13.0/#comptime&quot; target=&quot;_blank&quot;&gt;zig comptime&lt;/a&gt; 的知识，同时如果大家理解了这部分知识，那么 zoop 动态构造方法属性的部分实际不难理解。（建议同时也看看 &lt;a href=&quot;https://course.ziglang.cc/advanced/comptime&quot; target=&quot;_blank&quot;&gt;zig 圣经&lt;/a&gt; 中和 &lt;code&gt;comptime&lt;/code&gt; 有关的部分，写的很好）&lt;/p&gt;&lt;p&gt;下面我介绍一下 zoop 中用到的 &lt;code&gt;comptime&lt;/code&gt; 一些技巧，相信会对大家今后使用 zig 有帮助。&lt;/p&gt;&lt;h3 id=&quot;struct-is-omnipotent&quot;&gt;&lt;code&gt;struct&lt;/code&gt; 很万能&lt;/h3&gt;&lt;p&gt;&lt;code&gt;comptime&lt;/code&gt; 编程中，&lt;code&gt;struct&lt;/code&gt; 是你最好的朋友，想在不同的 &lt;code&gt;comptime&lt;/code&gt; 函数之间传递数据，最方便的方式，就是通过构造一个 &lt;code&gt;struct&lt;/code&gt;，把想传递的数据通过 &lt;code&gt;pub const xxx = ...&lt;/code&gt; 的方式传递出去，通过 &lt;code&gt;struct&lt;/code&gt; 保存数据最好的地方，就在于这个数据在运行时也是可用的（&lt;code&gt;struct&lt;/code&gt; 中的常量，是保存在 exe 的 &lt;code&gt;.data&lt;/code&gt; 区，运行时可见），&lt;a href=&quot;https://zhuyadong.github.io/zoop-docs/reference/tuple&quot; target=&quot;_blank&quot;&gt;zoop.tuple&lt;/a&gt; 就是通过这个方法实现的。&lt;/p&gt;&lt;h3 id=&quot;dynamically-construct-the-fields-of-struct-using-type&quot;&gt;动态构造 &lt;code&gt;struct&lt;/code&gt; 的字段，用 &lt;code&gt;@Type()&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;网上好像很少有关于 &lt;code&gt;@Type()&lt;/code&gt; 的使用说明，一般都是通过看 &lt;code&gt;zig.std&lt;/code&gt; 的代码来学习，那我这里就稍微说明一下，希望能对大家有帮助。 目前 zig 通过 &lt;code&gt;@Type()&lt;/code&gt;，能动态构造的 &lt;code&gt;struct&lt;/code&gt;，只有纯字段类型的 &lt;code&gt;struct&lt;/code&gt; (个人理解)。构造的方法，就是先把计算好的一个 &lt;code&gt;std.builtin.Type.StructField&lt;/code&gt; 数组传递给 &lt;code&gt;@Type()&lt;/code&gt; 来返回一个 &lt;code&gt;struct&lt;/code&gt;，比如以下代码：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;GenStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;builtin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;StructField&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;age&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;default_value&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;is_comptime&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;alignment&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@alignOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;default_value&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;is_comptime&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;alignment&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@alignOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@Type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Struct&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;layout&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fields&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;decls&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;is_tuple&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;GenStruct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样上面的 &lt;code&gt;MyStruct&lt;/code&gt; 就相当于：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MyStruct&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;zoop 动态构造 &lt;code&gt;Vtable&lt;/code&gt; 就是通过这个方法做到的，参考 &lt;a href=&quot;https://zhuyadong.github.io/zoop-docs/reference/principle#DefVtable&quot; target=&quot;_blank&quot;&gt;zoop.DefVtable 原理&lt;/a&gt; 和 &lt;a href=&quot;https://github.com/zhuyadong/zoop.git&quot; target=&quot;_blank&quot;&gt;zoop 源代码&lt;/a&gt;&lt;/p&gt;&lt;h3 id=&quot;dynamically-construct-the-function-of-struct-using-usingnamespace&quot;&gt;动态构造 &lt;code&gt;struct&lt;/code&gt; 的函数，用 &lt;code&gt;usingnamespace&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;要想定义 &lt;code&gt;struct&lt;/code&gt; 中的函数，理论上代码是一定要写在 &lt;code&gt;struct&lt;/code&gt; 中的，目前 zig 唯一留下的一个口子，就是 &lt;code&gt;usingnamespace&lt;/code&gt;，zoop 正是利用这个特性，来动态构造 &lt;code&gt;struct&lt;/code&gt; 的函数。&lt;/p&gt;&lt;p&gt;我们回顾一下 &lt;code&gt;Base&lt;/code&gt; 中定义 &lt;code&gt;setName&lt;/code&gt; 方法的代码：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zoop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Method&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里 &lt;code&gt;zoop.Method()&lt;/code&gt; 返回的是什么呢，返回的是：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过返回一个 &lt;code&gt;struct&lt;/code&gt; 的方式，在它的 &lt;code&gt;value&lt;/code&gt; 常量中保存了一个 &lt;code&gt;tuple&lt;/code&gt;，&lt;code&gt;tuple&lt;/code&gt; 有一个带有方法 &lt;code&gt;setName&lt;/code&gt; 的 &lt;code&gt;struct&lt;/code&gt; 元素。众所周知，&lt;code&gt;tuple&lt;/code&gt; 是可以各种组合的（参考 &lt;a href=&quot;https://zhuyadong.github.io/zoop-docs/reference/tuple&quot; target=&quot;_blank&quot;&gt;zoop.tuple&lt;/a&gt;），于是 zoop 通过 &lt;a href=&quot;https://zhuyadong.github.io/zoop-docs/reference/zoop#Fn&quot; target=&quot;_blank&quot;&gt;zoop.Fn&lt;/a&gt;，比如上例中 &lt;code&gt;Child&lt;/code&gt; 中的 &lt;code&gt;pub usingnamespace zoop.Fn(@This())&lt;/code&gt;，把 &lt;code&gt;Child&lt;/code&gt; 类型代入 &lt;code&gt;Base.Fn&lt;/code&gt; 中，就相当于在 &lt;code&gt;Child&lt;/code&gt; 内写了如下代码：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_import&quot;&gt;usingnamespace&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Child&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因而实现了对 &lt;code&gt;Base.setName()&lt;/code&gt; 方法的继承。&lt;/p&gt;&lt;h3 id=&quot;finding-vtable-and-parent-class-pointers-at-runtime-based-on-type&quot;&gt;运行时根据类型找 &lt;code&gt;Vtable&lt;/code&gt; 和父类指针&lt;/h3&gt;&lt;p&gt;这个功能的实现当时第一版是使用的 &lt;code&gt;std.StaticStringMap&lt;/code&gt; 保存了一个类中所有接口名到接口 &lt;code&gt;Vtable&lt;/code&gt; ，以及父类名到父类数据在本类中的地址偏移的映射。和 C++ 的 &lt;code&gt;dynamic_cast&lt;/code&gt; 比起来，性能是比较差的。后来看到西瓜大大发的一个链接 &lt;a href=&quot;https://github.com/SuperAuguste/cursed-zig-errors&quot; target=&quot;_blank&quot;&gt;点这里&lt;/a&gt;，忽然意识到这不就是我一直想要的 &lt;code&gt;comptime&lt;/code&gt; 全局变量么，我终于能写出 &lt;code&gt;typeId(comptime T: type) u32&lt;/code&gt; 这样的函数了：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;typeId&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@intCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@intFromError&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyerror&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;#&amp;quot;&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@typeName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里利用的，就是上面说到的链接中提示到的一个 zig 的 &lt;code&gt;error&lt;/code&gt; 类型的特点：访问 &lt;code&gt;error&lt;/code&gt; 中不存在的值，zig 会生成一个唯一的新值返回，并且这个在 &lt;code&gt;comptime&lt;/code&gt; 的时候同样有效。&lt;/p&gt;&lt;p&gt;有了 &lt;code&gt;typeId()&lt;/code&gt; 函数，上面的事从根据类型名查哈希表，就变成了在数组中找同样的 &lt;code&gt;typeid&lt;/code&gt; 了，整数比较对比字符串比较，那性能是快了好几倍的，根据我的了解，C++ 的 &lt;code&gt;dynamic_cast&lt;/code&gt; 也是在数组中比较 &lt;code&gt;typeid&lt;/code&gt;，这样一来，zoop 的动态转换性能，就和 C++ 差不多了。&lt;/p&gt;&lt;p&gt;利用这个新的 &lt;code&gt;typeId()&lt;/code&gt; 函数，zoop 怎么做动态类型转换，我从 zoop 中抄一段代码大家一看就明白：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;/// 返回一个函数，函数的功能是输入接口 `typeid`，返回针对 T 的该接口的 Vtable&lt;/span&gt;
&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;getVtableFunc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;VtableFunc&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 先找出 T 实现的所有接口&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ifaces&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IObject&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Interfaces&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 所有接口的 typeid 和 Vtable 编译时计算好并保存在 kvs 数组中&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;KV&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;typeid&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IObject&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Vtable&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kvs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ifaces&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;KV&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ifaces&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;iface&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kvs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;typeid&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;typeId&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;iface&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtable&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;makeVtable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;RealVtable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;iface&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;typeid&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;IObject&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Vtable&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 根据 typeid，从 kvs 数组中找出 Vtable&lt;/span&gt;
            &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kvs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;typeid&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;typeid&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面是找 &lt;code&gt;Vtable&lt;/code&gt; 的实现，找父类指针的实现原理是一样的，大家可以去看 zoop 源代码了解细节。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2024-08-12-zoop/</link>
        <pubDate>Mon, 12 Aug 2024 06:31:22 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-08-12-zoop/</guid>
      </item>
    
      <item>
        <title>社区新闻</title>
        <description>&lt;p&gt;我们会不定期举行线上会议来畅聊 Zig，感兴趣的朋友可以通过下面日历查看，或订阅&lt;a href=&quot;https://calendar.yandex.com/export/ics.xml?private_token=71fd8e02d7944f4e7ae44cc8a9b8877da9e9f2f1&amp;tz_id=Asia/Hong_Kong&quot; target=&quot;_blank&quot;&gt;这个 iCalendar&lt;/a&gt;。&lt;/p&gt;&lt;iframe src=&quot;https://calendar.yandex.com/embed/month?&amp;layer_ids=29400285&amp;tz_id=Asia/Hong_Kong&amp;layer_names=Zig 中文社区&quot; width=&quot;800&quot; height=&quot;450&quot; frameborder=&quot;0&quot; style=&quot;border: 1px solid #eee&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;线上会议地址：&lt;a href=&quot;https://discord.gg/36C7H47t47?event=1304329702512787466&quot; target=&quot;_blank&quot;&gt;https://discord.gg/36C7H47t47?event=1304329702512787466&lt;/a&gt;&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/news/</link>
        <pubDate>Sat, 03 Aug 2024 08:43:51 +0000</pubDate>
        <guid>https://ziglang.cc/post/news/</guid>
      </item>
    
      <item>
        <title>Zig 分配器的应用</title>
        <description>&lt;blockquote&gt;&lt;p&gt;原文地址： &lt;a href=&quot;https://www.openmymind.net/Leveraging-Zigs-Allocators/&quot; target=&quot;_blank&quot;&gt;https://www.openmymind.net/Leveraging-Zigs-Allocators/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;假设我们想为 Zig 编写一个 &lt;a href=&quot;https://github.com/karlseguin/http.zig&quot; target=&quot;_blank&quot;&gt;HTTP 服务器库&lt;/a&gt;。这个库的核心可能是线程池，用于处理请求。以简化的方式来看，它可能类似于：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO: 500 };&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;作为这个库的用户，您可能会编写一些动态内容的操作。如果假设在启动时为服务器提供分配器（Allocator），则可以将此分配器传递给动作：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO: 500 };&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这允许用户编写如下的操作：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;guest&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocPrint&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Hello {s}&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;虽然这是一个正确的方向，但存在明显的问题：分配的问候语从未被释放。我们的&lt;code&gt;run&lt;/code&gt;函数不能在写回应后就调用&lt;code&gt;allocator.free(conn.res.body)&lt;/code&gt;，因为在某些情况下，主体可能不需要被释放。我们可以通过使动作必须 &lt;code&gt;write()&lt;/code&gt; 回应并因此能够&lt;code&gt;free&lt;/code&gt;它所做的任何分配来结构化 API，但这将使得添加一些功能变得不可能，比如支持中间件。&lt;/p&gt;&lt;p&gt;最佳和最简单的方法是使用 &lt;code&gt;ArenaAllocator&lt;/code&gt; 。其工作原理很简单：当我们&lt;code&gt;deinit&lt;/code&gt;时，所有分配都被释放。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ArenaAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO: 500 };&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;std.mem.Allocator&lt;/code&gt; 是一个 “&lt;a href=&quot;https://www.openmymind.net/Zig-Interfaces/&quot; target=&quot;_blank&quot;&gt;接口&lt;/a&gt;” ，我们的动作无需更改。 &lt;code&gt;ArenaAllocator&lt;/code&gt; 对 HTTP 服务器来说是一个很好的选择，因为它们与请求绑定，具有明确/可理解的生命周期，并且相对短暂。虽然有可能滥用它们，但可以说：使用更多！&lt;/p&gt;&lt;p&gt;我们可以更进一步并重用相同的 Arena。这可能看起来不太有用，但是请看：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ArenaAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 魔法在此处！&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;retain_with_limit&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;8192&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO: 500 };&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们将 Arena 移出了循环，但重要的部分在内部：每个请求后，我们重置了 Arena 并保留最多 8K 内存。这意味着对于许多请求，我们无需访问底层分配器（&lt;code&gt;worker.server.allocator&lt;/code&gt;）。这种方法简化了内存管理。&lt;/p&gt;&lt;p&gt;现在想象一下，如果我们不能用 &lt;code&gt;retain_with_limit&lt;/code&gt; 重置 Arena，我们还能进行同样的优化吗？可以，我们可以创建自己的分配器，首先尝试使用固定缓冲区分配器（FixedBufferAllocator），如果分配适配，回退到 Arena 分配器。&lt;/p&gt;&lt;p&gt;这里是 &lt;code&gt;FallbackAllocator&lt;/code&gt; 的完整示例：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FallbackAllocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fallback&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fba&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;FixedBufferAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FallbackAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtable&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;alloc&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;resize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;free&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr_align&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ra&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FallbackAllocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@alignCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;rawAlloc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr_align&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ra&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;keyword_operator&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fallback&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;rawAlloc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr_align&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ra&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;buf_align&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;new_len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ra&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FallbackAllocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@alignCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fba&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;ownsPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;rawResize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf_align&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;new_len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ra&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fallback&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;rawResize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf_align&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;new_len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ra&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// we noop this since, in our specific case, we know&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// the fallback is an arena, which won&amp;apos;t free individual items&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们的&lt;code&gt;alloc&lt;/code&gt;实现首先尝试使用我们定义的”主”分配器进行分配。如果失败，我们会使用”备用”分配器。作为&lt;code&gt;std.mem.Allocator&lt;/code&gt;接口的一部分，我们需要实现的&lt;code&gt;resize&lt;/code&gt;方法会确定正在尝试扩展内存的所有者，并然后调用其&lt;code&gt;rawResize&lt;/code&gt;方法。为了保持代码简单，我在这里省略了&lt;code&gt;free&lt;/code&gt;方法的具体实现——在这种特定情况下是可以接受的，因为我们计划使用”主”分配器作为&lt;code&gt;FixedBufferAllocator&lt;/code&gt;，而”备用”分配器则会是&lt;code&gt;ArenaAllocator&lt;/code&gt;（因此所有释放操作会在 arena 的&lt;code&gt;deinit&lt;/code&gt;或&lt;code&gt;reset&lt;/code&gt;时进行）。&lt;/p&gt;&lt;p&gt;接下来我们需要改变我们的&lt;code&gt;run&lt;/code&gt;方法以利用这个新的分配器：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 这是 FixedBufferAllocator 底层的内存&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;8192&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 分配 8K 字节的内存用于存储数据&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 完成后释放内存&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fba&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;FixedBufferAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 初始化 FixedBufferAllocator&lt;/span&gt;

    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fba&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 重置 FixedBufferAllocator，准备处理下一个请求&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ArenaAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 初始化 ArenaAllocator 用于分配额外内存&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fallback&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FallbackAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fba&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fba&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;primary&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fba&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fallback&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 创建 FallbackAllocator，包含 FixedBufferAllocator 和 ArenaAllocator&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 路由请求到对应的动作处理函数&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fallback&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 处理动作执行中的错误 };&lt;/span&gt;

        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 写回响应信息给客户端&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种方法实现了类似于在&lt;code&gt;retain_with_limit&lt;/code&gt;中重置 arena 的功能。我们创建了一个可以重复使用的&lt;code&gt;FixedBufferAllocator&lt;/code&gt;，用于处理每个请求的 8K 字节内存需求。由于一个动作可能需要更多的内存，我们仍然需要&lt;code&gt;ArenaAllocator&lt;/code&gt;来提供额外的空间。通过将&lt;code&gt;FixedBufferAllocator&lt;/code&gt;和&lt;code&gt;ArenaAllocator&lt;/code&gt;包裹在我们的&lt;code&gt;FallbackAllocator&lt;/code&gt;中，我们可以确保任何分配都首先尝试使用（非常快的）&lt;code&gt;FixedBufferAllocator&lt;/code&gt;，当其空间用尽时，则会切换到&lt;code&gt;ArenaAllocator&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;我们通过暴露&lt;code&gt;std.mem.Allocator&lt;/code&gt;接口，可以调整如何工作而不破坏&lt;code&gt;greet&lt;/code&gt;。这不仅简化了资源管理（例如通过&lt;code&gt;ArenaAllocator&lt;/code&gt;），而且通过重复使用分配来提高了性能（类似于我们做的&lt;code&gt;retain_with_limit&lt;/code&gt;或&lt;code&gt;FixedBufferAllocator&lt;/code&gt;的操作）。&lt;/p&gt;&lt;p&gt;这个示例应该能突出显示我认为明确的分配器提供的两个实际优势：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;简化资源管理（通过类似&lt;code&gt;ArenaAllocator&lt;/code&gt;的方式）&lt;/li&gt;&lt;li&gt;通过重用分配来提高性能（例如我们之前在 &lt;code&gt;retain_with_limit&lt;/code&gt; 或 &lt;code&gt;FixedBufferAllocator&lt;/code&gt; 时所做的一样）&lt;/li&gt;&lt;/ol&gt;</description>
        <link>https://ziglang.cc/post/2024-06-16-leveraging-zig-allocator/</link>
        <pubDate>Sun, 16 Jun 2024 04:11:44 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-06-16-leveraging-zig-allocator/</guid>
      </item>
    
      <item>
        <title>HashMap 原理介绍下篇</title>
        <description>&lt;p&gt;在&lt;a href=&quot;https://ziglang.cc/post/2024-06-10-zig-hashmap-1/&quot;&gt;第一部分&lt;/a&gt;中，我们探讨了六种 &lt;code&gt;HashMap&lt;/code&gt; 变体之间的关系以及每种变体为开发人员提供的不同功能。我们主要关注如何为各种数据类型定义和初始化 &lt;code&gt;HashMap&lt;/code&gt;，并讨论了当 &lt;code&gt;StringHashMap&lt;/code&gt; 或 &lt;code&gt;AutoHashMap&lt;/code&gt; 不支持的类型时使用自定义 &lt;code&gt;hash&lt;/code&gt; 和 &lt;code&gt;eql&lt;/code&gt; 函数的重要性。在这篇文章中，我们将更深入地研究键和值的存储、访问方式以及我们在它们生命周期管理中的责任。&lt;/p&gt;&lt;p&gt;Zig 的哈希表内部采用两个切片结构：一个用于存放键（key），另一个用于存储对应的值（value）。通过应用哈希函数计算得到的哈希码被用来在这些数组中定位条目。从基础代码出发，比如：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;StringHashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defer&lt;/span&gt; lookup&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9001&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Paul&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1234&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样的操作在哈希表中形成了一个类似如下的可视化表示：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;keys:               values:
       --------          --------
       | Paul |          | 1234 |     @mod(hash(&amp;quot;Paul&amp;quot;), 5) == 0
       --------          --------
       |      |          |      |
       --------          --------
       |      |          |      |
       --------          --------
       | Goku |          | 9001 |    @mod(hash(&amp;quot;Goku&amp;quot;), 5) == 3
       --------          --------
       |      |          |      |
       --------          --------
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当我们使用模运算（如 &lt;code&gt;@mod&lt;/code&gt;）将哈希码映射到数组中一个固定数量的槽位上时，我们就有了条目的理想位置。这里的”理想”是指哈希函数可能会为不同的键生成相同的哈希值；在计算时，通过数组大小进行取模有助于处理这种碰撞情况。然而，在忽略可能的冲突前提下，以上就是我们当前哈希表的基本视图。&lt;/p&gt;&lt;p&gt;一旦哈希表被填满到一定程度（如第一部分中提到，Zig 的默认填充因子为 80%），它就需要进行扩展来容纳更多值，同时保持常数时间性能的查找操作。哈希表的扩展过程类似于动态数组的扩容，我们分配一个新数组，并将原始数组中的值复制到新数组（通常会增加原数组大小的两倍作为简单算法）。然而，在处理哈希表时，简单的键值对复制是不够的。因为我们不能使用一种哈希方法如 &lt;code&gt;@mod(hash(&amp;quot;Goku&amp;quot;), 5)&lt;/code&gt; 并期望在另一个不同的哈希方法下找到相同的条目如 &lt;code&gt;@mod(hash(&amp;quot;Goku&amp;quot;), 10)&lt;/code&gt;（请注意，因为数组大小已增加，5 变成了 10）。&lt;/p&gt;&lt;p&gt;这个基本的可视化表示将贯穿本文大部分内容，并且不断强调条目的位置需要保持一致性和可预测性。即使哈希表需要在增长时从一个底层数组移动到另一个（即当填充因子达到一定阈值并要求扩大以容纳更多数据时），这一事实是我们将反复回顾的主题。&lt;/p&gt;&lt;h2 id=&quot;value-management&quot;&gt;值管理&lt;/h2&gt;&lt;p&gt;如果我们对上述代码片段进行扩展，并调用 &lt;code&gt;lookup.get(&amp;quot;Paul&amp;quot;)&lt;/code&gt;，返回的值将是 &lt;code&gt;1234&lt;/code&gt;。在处理像 &lt;code&gt;i32&lt;/code&gt; 这样的原始类型时，很难直观地理解 &lt;code&gt;get&lt;/code&gt; 方法和它的可选返回类型 &lt;code&gt;?i32&lt;/code&gt; 或更通用的 &lt;code&gt;?V&lt;/code&gt;（其中 &lt;code&gt;V&lt;/code&gt; 表示任何值类型）之间的区别。考虑到这一点，让我们通过替换 &lt;code&gt;i32&lt;/code&gt; 为一个封装了更多信息的 &lt;code&gt;User&lt;/code&gt; 类型来展示这一概念：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 示例：如果 i32 被替换为一个 User 类型，则会涉及更复杂的数据结构和访问逻辑。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在上述场景中，我们引入了一个新的类型 &lt;code&gt;User&lt;/code&gt;，用于演示 &lt;code&gt;get&lt;/code&gt; 方法返回可选值的概念。通过这种方式，我们可以直观地理解 &lt;code&gt;get&lt;/code&gt; 和 &lt;code&gt;getPtr&lt;/code&gt; 方法之间的区别，并根据实际需要选择合适的方法来处理不同的数据访问需求。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;StringHashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9000&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;{any}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即使我们设置了 &lt;code&gt;user.super = true&lt;/code&gt;，在 &lt;code&gt;lookup&lt;/code&gt; 中的 &lt;code&gt;User&lt;/code&gt; 的值仍然是 &lt;code&gt;false&lt;/code&gt;。这是因为在 Zig 中，赋值是通过复制完成的。如果我们保持代码不变，但将 &lt;code&gt;lookup.get&lt;/code&gt; 改为 &lt;code&gt;lookup.getPtr&lt;/code&gt;，它将起作用。我们仍然在做赋值，因此仍然在复制一个值，但我们复制的值是哈希表中 &lt;code&gt;User&lt;/code&gt; 的地址，而不是 &lt;code&gt;user&lt;/code&gt; 本身。&lt;/p&gt;&lt;p&gt;&lt;code&gt;getPtr&lt;/code&gt; 允许我们获取哈希表中值的引用。如上所示，这具有行为意义；我们可以直接修改存储在哈希表中的值。这也具有性能意义，因为复制大值可能会很昂贵。但是考虑我们上面的可视化，并记住，随着哈希表的填满，值可能会重新定位。考虑到这一点，你能解释为什么这段代码会崩溃吗？：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// change the type, just to make it easier to write this snippet&lt;/span&gt;
	&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// the same would happen with our above StringHashMap(User)&lt;/span&gt;
	&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;AutoHashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果 &lt;code&gt;first.* = 200;&lt;/code&gt; 的语法让您感到困惑，那么我们在操作指针，并向其指定的地址写入一个值。这里的指针指向了值数组中某个索引的位置，因此这种语法实际上是在数组内部直接设置了一个值。问题在于，在我们的插入循环过程中，哈希表正在增长，导致底层键和值被重新分配并移动。&lt;code&gt;getPtr&lt;/code&gt; 函数返回的指针不再有效。在撰写本文时，哈希表默认大小为 8，填充因子是 80%。如果我们在遍历范围 &lt;code&gt;0..5&lt;/code&gt; 时运行代码一切正常，但当增加一次迭代至 &lt;code&gt;0..6&lt;/code&gt;（即尝试访问 &lt;code&gt;array[6]&lt;/code&gt;）时，由于增长操作导致崩溃。在常规使用场景中，此问题通常不构成问题；您不太可能在修改哈希表时持有对某个条目的引用。但是，理解这种情况的发生以及其原因将帮助我们更好地利用其他返回值和键指针的哈希表功能。&lt;/p&gt;&lt;p&gt;回到我们的 &lt;code&gt;User&lt;/code&gt; 示例，如果我们将 &lt;code&gt;lookup&lt;/code&gt; 的类型从 &lt;code&gt;std.StringHashMap(User)&lt;/code&gt; 改为 &lt;code&gt;std.StringHashMap(*User)&lt;/code&gt; 会怎样？最大的影响将是值的生命周期。使用原来的 &lt;code&gt;std.StringHashMap(User)&lt;/code&gt;，我们可以说 &lt;code&gt;lookup&lt;/code&gt; 拥有这些值——我们插入的用户嵌入在哈希表的值数组中。这使得生命周期管理变得容易，当我们 &lt;code&gt;deinit&lt;/code&gt; 我们的 &lt;code&gt;lookup&lt;/code&gt; 时，底层的键和值数组会被释放。&lt;/p&gt;&lt;p&gt;我们的 &lt;code&gt;User&lt;/code&gt; 有一个 &lt;code&gt;name: []const u8&lt;/code&gt; 字段。我们的示例使用字符串字面量，它在程序的生命周期中静态存在。然而，如果我们的 &lt;code&gt;name&lt;/code&gt; 是动态分配的，我们必须显式地释放它。我们将在更详细地探讨指针值时涵盖这一点。&lt;/p&gt;&lt;p&gt;使用 &lt;code&gt;*User&lt;/code&gt; 打破了这种所有权。我们的哈希表存储指针，但它不拥有指针所指向的内容。尽管调用了 &lt;code&gt;lookup.deinit&lt;/code&gt;，这段代码会导致用户泄漏：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;StringHashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;goku&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;goku&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9000&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;goku&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;让我们将其可视化：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;lookup
 ===============================
 ║  keys:       values:        ║
 ║  --------    -------------  ║
 ║  | Goku* |   | 1024d4000 | ----&amp;gt; -------------
 ║  --------    -------------  ║    |   9000    |
 ║  |       |   |           |  ║    -------------
 ║  --------    -------------  ║    | 1047300e4 |---&amp;gt; -----------------
 ===============================    -------------     | G | o | k | u |
                                     |    4      |     -----------------
                                     -------------
                                     |   false   |
                                     -------------
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们将会在下一节讨论键，现在为了简单起见我们使用“Goku”。&lt;/p&gt;&lt;p&gt;双线框是我们的 &lt;code&gt;lookup&lt;/code&gt;，表示它拥有并负责的内存。我们放入哈希表的引用将指向框外的值。这有许多含义。最重要的是，这意味着值的生命周期与哈希表的生命周期分离，调用 &lt;code&gt;lookup.deinit&lt;/code&gt; 不会释放它们。&lt;/p&gt;&lt;p&gt;有一种常见情况是我们想使用指针并将值的生命周期与哈希表相关联。回想我们崩溃的程序，当对哈希表值的指针变得无效时。正如我所说，这通常不是问题，但在更高级的场景中，你可能希望不同部分的代码引用也存在于哈希表中的值。让我们重新审视上面的可视化，并思考如果我们的哈希表增长并重新定位键和值数组会发生什么：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;
 &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;
 ║  &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;       &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;        ║
 ║  &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;  ║
 ║  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;       &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  ║
 ║  &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;  ║
 ║  &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;  ║
 ║  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;       &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  ║
 ║  &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;  ║
 ║  &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;  ║
 ║  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Goku&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1024&lt;/span&gt;d4000 &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
 ║  &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;  ║    &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;number&quot;&gt;9000&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
 ║  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;       &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  ║    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
 ║  &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;  ║    &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;number_float&quot;&gt;1047300e4&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
 &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt;    &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;     &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;G&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
                                     &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;    &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;      &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;     &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
                                     &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
                                     &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;   &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
                                     &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这两个数组已经增长、重新分配，并且我们的条目索引已重新计算，但我们实际的 &lt;code&gt;User&lt;/code&gt;（也就是 &lt;code&gt;Goku&lt;/code&gt;）仍然驻留在堆中的同一位置（内存位置 1047300e4）。就像 &lt;code&gt;deinit&lt;/code&gt; 不会改变双线框外的任何内容一样，其他变化（如增长）也不会改变它们。&lt;/p&gt;&lt;p&gt;一般来说，你是否应该存储值或指向值的指针将是显而易见的。这主要是因为像 &lt;code&gt;getPtr&lt;/code&gt; 这样的方法使我们能够直接从哈希表中高效地检索和修改值。无论哪种方式，我们都可以获得性能上的好处，所以性能不是主要考虑因素。重要的是值是否需要比哈希表存活更久和/或在哈希表发生变化时对值的引用是否需要存在（并因此保持有效）。&lt;/p&gt;&lt;p&gt;在哈希表和引用的值应该链接的情况下，我们需要在调用 &lt;code&gt;lookup.deinit&lt;/code&gt; 之前遍历这些值并清理它们：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;var&lt;/span&gt; it &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;valueIterator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    lookup&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果解引用 (&lt;code&gt;value_ptr.*&lt;/code&gt;) 看起来不对劲，请回到可视化。我们的 &lt;code&gt;valueIterator&lt;/code&gt; 给我们数组中值的指针，而数组中的值是 &lt;code&gt;*User&lt;/code&gt;。因此，&lt;code&gt;value_ptr&lt;/code&gt; 是 &lt;code&gt;**User&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;无论我们是存储 &lt;code&gt;User&lt;/code&gt; 还是 &lt;code&gt;*User&lt;/code&gt;，值中任何已分配的字段始终是我们的责任。在一个真实的应用程序中，你的用户名称不会是字符串字面量，它们会是动态分配的。在这种情况下，我们上面的 while 循环需要改为：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即使我们的值是 &lt;code&gt;User&lt;/code&gt;，其字段也是我们的责任（认为 &lt;code&gt;lookup.deinit&lt;/code&gt; 会知道如何/需要释放什么有点荒谬）：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在最后一种情况下，由于我们存储的是 &lt;code&gt;User&lt;/code&gt; 而不是 &lt;code&gt;*User&lt;/code&gt;，我们的 &lt;code&gt;value_ptr&lt;/code&gt; 是指向 &lt;code&gt;User&lt;/code&gt; 的指针（不像之前那样是指向指针的指针）。&lt;/p&gt;&lt;h2 id=&quot;keys&quot;&gt;Keys&lt;/h2&gt;&lt;p&gt;我们可以开始和结束这一节：我们关于值的所有内容同样适用于键。这是 100% 正确的，但这在某种程度上不太直观。大多数开发人员很快就能理解，存储在哈希表中的堆分配的 &lt;code&gt;User&lt;/code&gt; 实例有其自身的生命周期，需要显式管理/释放。但由于某些原因，这对于键来说并不那么明显。&lt;/p&gt;&lt;p&gt;像值一样，如果我们的键是原始类型（例如整数），我们不必做任何特别的处理。原始类型的键直接存储在哈希表的键数组中，因此其生命周期和内存与哈希表绑定。这是一种非常常见的情况。但另一种常见情况是使用 &lt;code&gt;std.StringHashMap&lt;/code&gt; 的字符串键。这常常让刚接触 Zig 的开发人员感到困惑，但你需要保证字符串键在哈希表使用它们期间始终有效。而且，如果这些键是动态分配的，你需要确保在不再使用时释放它们。这意味着对键进行与值相同的处理。&lt;/p&gt;&lt;p&gt;让我们再次可视化我们的哈希表，但这次正确表示一个字符串键：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;lookup
 ===================================
 ║  keys:       values:            ║
 ║  -------------    ------------  ║
 ║  | 1047300e4 |   | 1024d4000 | ----&amp;gt; -------------
 ║  -------------   -------------  ║    |   9000    |
 ║  |           |   |           |  ║    -------------
 ║  -------------   -------------  ║    | 1047300e4 |---&amp;gt; -----------------
 ===================================    -------------     | G | o | k | u |
                                         |    4      |     -----------------
                                         -------------
                                         |   false   |
                                         -------------
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在这个例子中，我们的键实际上是 &lt;code&gt;user.name&lt;/code&gt;。将键作为值的一部分是非常常见的。这里是它可能的样子：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9000&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 模拟来自动态源（如数据库）的名称&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dupe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; lookup&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这种情况下，我们之前的清理代码是足够的，因为我们已经在释放作为我们键的 &lt;code&gt;user.name&lt;/code&gt;：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;var&lt;/span&gt; it &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    lookup&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但在键不是值的一部分的情况下，我们需要迭代并释放这些键。在许多情况下，你需要同时迭代键和值并释放它们。我们可以通过释放键引用的名称而不是用户来模拟这一点：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;var&lt;/span&gt; it &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 这个..&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;key_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 和下面的是一样的，但仅仅因为 user.name 是我们的键&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// allocator.free(user.name);&lt;/span&gt;

        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    lookup&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们使用 &lt;code&gt;iterator()&lt;/code&gt; 而不是 &lt;code&gt;iteratorValue()&lt;/code&gt; 来访问 &lt;code&gt;key_ptr&lt;/code&gt; 和 &lt;code&gt;value_ptr&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;最后要考虑的是如何从我们的 &lt;code&gt;lookup&lt;/code&gt; 中移除值。尽管使用了改进的清理逻辑，这段代码仍会导致键和堆分配的 &lt;code&gt;User&lt;/code&gt; 泄漏：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;StringHashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;var&lt;/span&gt; it &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;key_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    lookup&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

const user &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
user&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9000&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 模拟来自动态源（如数据库）的名称&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dupe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; lookup&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 我们加上了这行！&lt;/span&gt;
_ &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后一行从我们的哈希表中移除了条目，所以我们的清理例程不再迭代它，也不会释放名称或用户。我们需要使用 &lt;code&gt;fetchRemove&lt;/code&gt; 而不是 &lt;code&gt;remove&lt;/code&gt; 来获取被移除的键和值：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fetchRemove&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kv&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;fetchRemove&lt;/code&gt; 不返回键和值的指针，而是返回实际的键和值。这并不会改变我们的使用方式，但显然为什么返回键和值而不是指针是很明显的，因为从哈希表中移除的条目，不再有指向哈希表中键和值的有效指针——它们已经被移除了。&lt;/p&gt;&lt;p&gt;所有这些都假设你的值和键在从哈希表中移除时需要被释放/失效。有些情况下，你的值（更少见的是键）的生命周期与它们在哈希表中的存在完全无关。在这些情况下，你需要在适合你的应用程序的情况下释放内存。没有通用的模式或指导适用。&lt;/p&gt;&lt;p&gt;对于大多数情况，在处理非原始键或值时，关键是当你调用哈希表的 &lt;code&gt;deinit&lt;/code&gt; 时，你为键和值分配的任何内存不会被自动释放；你需要自己处理。&lt;/p&gt;&lt;h2 id=&quot;getorput&quot;&gt;getOrPut&lt;/h2&gt;&lt;p&gt;虽然我们已经讨论过的内容有很多含义，但对我来说，直接暴露键和值指针的最大好处之一是 &lt;code&gt;getOrPut&lt;/code&gt; 方法。&lt;/p&gt;&lt;p&gt;如果我让你在 Go 或大多数语言中存储带名称的计数器，你会写出类似这样的代码：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;go&quot;&gt;&lt;span class=&quot;variable&quot;&gt;count&lt;/span&gt;, &lt;span class=&quot;variable&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;counters&lt;/span&gt;[&lt;span class=&quot;variable&quot;&gt;name&lt;/span&gt;]
&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;exists&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;false&lt;/span&gt; {
    &lt;span class=&quot;variable&quot;&gt;counters&lt;/span&gt;[&lt;span class=&quot;variable&quot;&gt;name&lt;/span&gt;] &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
} &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
    &lt;span class=&quot;variable&quot;&gt;counters&lt;/span&gt;[&lt;span class=&quot;variable&quot;&gt;name&lt;/span&gt;] &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;variable&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码需要两次查找。尽管我们被训练成不考虑哈希表访问通常为 O(1)，实际情况是操作次数越少运行速度越快；而计算哈希码并非最经济的操作（其性能取决于键的类型和长度），碰撞还会增加额外开销。「getOrPut」方法通过返回一个值指针和一个指示是否找到该值的布尔值来解决这个问题。&lt;/p&gt;&lt;p&gt;换句话说，使用 &lt;code&gt;getOrPut&lt;/code&gt; 我们要么获得一个指向找到的值的指针，要么获得一个指向应放置项位置的指针。我们还得到一个布尔值，用于指示是哪种情况。这使得上述插入或更新操作仅需一次查找：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gop&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;counters&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getOrPut&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;found_existing&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value_ptr&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当然，只要不对哈希表进行修改，&lt;code&gt;value_ptr&lt;/code&gt; 就应被视为有效。顺便提一句，这同样适用于我们通过 &lt;code&gt;iterator()&lt;/code&gt;、&lt;code&gt;valueIterator&lt;/code&gt; 和 &lt;code&gt;keyIterator&lt;/code&gt; 获取的迭代键和值，原因相同。&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot;&gt;结论&lt;/h2&gt;&lt;p&gt;希望你现在对使用「std.HashMap」、「std.AutoHashMap」和「std.StringHashMap」以及它们的「unmanaged」变体感到更加得心应手。虽然你可能永远不需要提供自己的上下文（例如「hash」和「eql」函数），但了解这是一个选项是有益的。在日常编程中，可视化数据尤其有用，尤其是在使用指针和添加间接层次时。每当我处理 &lt;code&gt;value_ptr&lt;/code&gt; 或 &lt;code&gt;key_ptr&lt;/code&gt; 时，我都会想到这些切片以及值或键与这些切片中值或键的实际地址之间的区别。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;原文地址：&lt;a href=&quot;https://www.openmymind.net/Zigs-HashMap-Part-2/&quot; target=&quot;_blank&quot;&gt;https://www.openmymind.net/Zigs-HashMap-Part-2/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;</description>
        <link>https://ziglang.cc/post/2024-06-11-zig-hashmap-2/</link>
        <pubDate>Tue, 11 Jun 2024 07:57:06 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-06-11-zig-hashmap-2/</guid>
      </item>
    
      <item>
        <title>HashMap 原理介绍上篇</title>
        <description>&lt;blockquote&gt;&lt;p&gt;阅读这篇文章的前提是了解 &lt;a href=&quot;https://www.openmymind.net/learning_zig/generics/&quot; target=&quot;_blank&quot;&gt;Zig 的范型实现&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;如大多数哈希映射实现一样，Zig 的 &lt;code&gt;std.HashMap&lt;/code&gt; 依赖于两个函数：&lt;code&gt;hash(key: K) u64&lt;/code&gt; 和 &lt;code&gt;eql(key_a: K, key_b: K) bool&lt;/code&gt;。其中，哈希函数接收一个键并返回一个无符号的 64 位整数作为哈希码。相同的关键字总是会返回相同的哈希码。然而，为了处理不同的键可能生成相同哈希码的情况（即碰撞），我们还需要 &lt;code&gt;eql&lt;/code&gt; 函数来确定两个键是否相等。&lt;/p&gt;&lt;p&gt;这是一些标准做法，但 Zig 的实现有一些特定的细节值得关注。尤其是考虑到标准库中包含多种哈希映射类型以及文档似乎不完整且令人困惑这一点。具体来说，有六种哈希映射变体：&lt;code&gt;std.HashMap&lt;/code&gt;, &lt;code&gt;std.HashMapUnmanaged&lt;/code&gt;, &lt;code&gt;std.AutoHashMap&lt;/code&gt;, &lt;code&gt;std.AutoHashMapUnmanaged&lt;/code&gt;, &lt;code&gt;std.StringHashMap&lt;/code&gt;, 和 &lt;code&gt;std.StringHashMapUnmanaged&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;&lt;code&gt;std.HashMapUnmanaged&lt;/code&gt; 包含了实现的主要部分。其他五个都是对它的简单包装。由于这些变体通过一个名为“unmanaged”的字段进行包装，因此这五种类型的文档处理不清晰。&lt;/p&gt;&lt;p&gt;如果查看 &lt;code&gt;std.HashMap&lt;/code&gt; 的 &lt;code&gt;put&lt;/code&gt; 方法，会发现一个经常重复的应用模式：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;unmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;putContext&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;正如我所说，大部分繁重的工作都由 &lt;code&gt;std.HashMapUnmanaged&lt;/code&gt; 完成，其他变体通过一个名为 &lt;code&gt;unmanaged&lt;/code&gt; 的字段对其进行封装。&lt;/p&gt;&lt;h2 id=&quot;unmanaged&quot;&gt;Unmanaged&lt;/h2&gt;&lt;p&gt;在 Zig 标准库中随处可见的类型命名约定是 &lt;code&gt;unmanaged&lt;/code&gt;。这种命名方式表明所涉及的类型不维护 &lt;code&gt;allocator&lt;/code&gt;。任何需要分配内存的方法都会显式地将 &lt;code&gt;allocator&lt;/code&gt; 作为参数传递。要实际看到这一点，可以考虑下面这个链表的例子：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们的初始化函数接受并存储一个 &lt;code&gt;std.mem.Allocator&lt;/code&gt;。这个分配器随后将在 append 和 deinit 操作中根据需要使用。这在 Zig 中是一个常见的模式。上述 &lt;code&gt;unmanaged&lt;/code&gt; 版本只有细微的差别：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;LinkedListUnmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// .. same as above&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Node is the same as above&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;整体而言，代码已经是高质量的，上面的更改是细微优化的一部分。 我们不再有一个 &lt;code&gt;allocator&lt;/code&gt; 字段。&lt;code&gt;append&lt;/code&gt; 和 &lt;code&gt;deinit&lt;/code&gt; 函数都多了一个额外的参数：&lt;code&gt;allocator&lt;/code&gt;。因为我们不再需要存储 &lt;code&gt;allocator&lt;/code&gt;，我们能够仅用默认值初始化 &lt;code&gt;LinkedListUnmanaged(T)&lt;/code&gt;（即 &lt;code&gt;head: ?*Node = null&lt;/code&gt;），并且能够完全移除 &lt;code&gt;init&lt;/code&gt; 函数。这不是未管理类型的要求，但这是常见的做法。要创建一个 &lt;code&gt;LinkedListUnmanaged(i32)&lt;/code&gt;，你可以这样做：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ll&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;LinkedListUnmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这看起来有点神秘，但这是标准的 Zig。&lt;code&gt;LinkedListUnmanaged(i32)&lt;/code&gt; 返回一个类型，所以上面的做法和执行 &lt;code&gt;var user = User{}&lt;/code&gt; 并依赖 &lt;code&gt;User&lt;/code&gt; 的默认字段值没有区别。&lt;/p&gt;&lt;p&gt;你可能会好奇 &lt;code&gt;unmanaged&lt;/code&gt; 类型有什么用？但在我们回答这个问题之前，让我们考虑一下提供我们的 LinkedList 的 &lt;code&gt;managed&lt;/code&gt; 和 &lt;code&gt;unmanaged&lt;/code&gt; 版本有多容易。我们保持我们的 &lt;code&gt;LinkedListUnmanaged&lt;/code&gt; 如原样，并改变我们的 &lt;code&gt;LinkedList&lt;/code&gt; 来包装它：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;unmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;LinkedListUnmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;unmanaged&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;unmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;unmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;LinkedListUnmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种简单的组合方式，正如我们上面所见，与各种哈希映射类型包装 &lt;code&gt;std.HashMapUnmanaged&lt;/code&gt; 的方式相同。&lt;/p&gt;&lt;p&gt;&lt;code&gt;unmanaged&lt;/code&gt; 类型有几个好处。最重要的是它们更加明确。与知道像 &lt;code&gt;LinkList(T)&lt;/code&gt; 这样的类型可能在某个时刻需要分配内存不同，未管理变体的明确 API 标识了进行分配/释放的特定方法。这可以帮助减少意外并为调用者提供更大的控制权。未管理类型的次要好处是它们通过不引用分配器节省了一些内存。一些应用可能需要存储成千上万甚至更多这样的结构，在这种情况下，这种节省可以累积起来。&lt;/p&gt;&lt;p&gt;为了简化，本文的其余部分不会再提到 &lt;code&gt;unmanaged&lt;/code&gt;。我们看到关于 &lt;code&gt;StringHashMap&lt;/code&gt; 或 &lt;code&gt;AutoHashMap&lt;/code&gt; 或 &lt;code&gt;HashMap&lt;/code&gt; 的任何内容同样适用于它们的 Unmanaged 变体。&lt;/p&gt;&lt;h2 id=&quot;hashmap-and-autohashmap&quot;&gt;HashMap 与 AutoHashMap&lt;/h2&gt;&lt;p&gt;std.HashMap 是一个泛型类型，它接受两个类型参数：键的类型和值的类型。正如我们所见，哈希映射需要两个函数：hash 和 eql。这两个函数合起来被称为“上下文 (context)”。这两个函数都作用于键，并且没有一个单一的 hash 或 eql 函数适用于所有类型。例如，对于整数键，eql 将是 &lt;code&gt;a_key == b_key&lt;/code&gt;；而对于 &lt;code&gt;[]const u8&lt;/code&gt; 键，我们希望使用 &lt;code&gt;std.mem.eql(u8, a_key, b_key)&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;当我们使用 std.HashMap 时，我们需要提供上下文（这两个函数）。我们不久后将讨论这一点，但现在我们可以依赖 std.AutoHashMap，它为我们自动生成这些函数。可能会让你惊讶的是，AutoHashMap 甚至可以为更复杂的键生成上下文。以下操作是有效的： 以下是修正后的代码：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;AutoHashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;active&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9001&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;active&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pending&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;login_ids&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// You intended to use an array here instead of a slice.&lt;/span&gt;
    &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改后的代码中，我修正了 &lt;code&gt;User&lt;/code&gt; 结构体内部的 &lt;code&gt;login_ids&lt;/code&gt; 从切片（&lt;code&gt;[]T&lt;/code&gt;）改为了数组 (&lt;code&gt;[N]T&lt;/code&gt;)。在 Zig 中，使用数组可以避免与切片相关的不确定性和模糊性问题。&lt;/p&gt;&lt;p&gt;此外，我还优化了 &lt;code&gt;std.heap.GeneralPurposeAllocator&lt;/code&gt; 的初始化方式。原本的 &lt;code&gt;.{}&lt;/code&gt; 是不必要的，并且已经更新至更简洁的形式。 你会被原谅，如果你认为 &lt;code&gt;StringHashMap(V)&lt;/code&gt; 是 &lt;code&gt;AutoHashMap([], V)&lt;/code&gt; 的别名。但正如我们刚看到的，&lt;code&gt;AutoHashMap&lt;/code&gt; 不支持切片键。我们可以确认这一点。尝试运行：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;AutoHashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;over&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9000&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;得到下面的错误：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;error: &lt;code&gt;std.auto_hash.autoHash&lt;/code&gt; does not allow slices here (&lt;code&gt;[]const u8&lt;/code&gt;) because the intent is unclear. Consider using &lt;code&gt;std.StringHashMap&lt;/code&gt; for hashing the contents of &lt;code&gt;[]const u8&lt;/code&gt;. Alternatively, consider using &lt;code&gt;std.auto_hash.hash&lt;/code&gt; or providing your own hash function instead.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;正如我之前所说，问题不是切片不能被哈希或比较，而是有些情况下，切片只有在引用相同内存时才会被认为是相等的，而另一些情况下，两个切片如果它们的元素相同就会被认为是相等的。但是，对于字符串，大多数人期望“teg”无论存储在哪里都应该等于“teg”。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;character&quot;&gt;&amp;apos;T&amp;apos;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;character&quot;&gt;&amp;apos;e&amp;apos;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;character&quot;&gt;&amp;apos;g&amp;apos;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name2&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dupe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;eql1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;eql2&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;{any}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;{any}&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;eql1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;eql2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上述程序打印“false”，然后打印“true”。&lt;code&gt;std.meta.eql&lt;/code&gt;使用 &lt;code&gt;a.ptr == b.ptr&lt;/code&gt; 和 &lt;code&gt;a.len == b.len&lt;/code&gt; 来比较指针。但具体到字符串，大多数程序员可能期望 &lt;code&gt;std.mem.eql&lt;/code&gt; 的行为，它比较字符串内部的字节。&lt;/p&gt;&lt;p&gt;因此，就像 &lt;code&gt;AutoHashMap&lt;/code&gt; 包装了带有自动生成上下文的 &lt;code&gt;HashMap&lt;/code&gt; 一样，&lt;code&gt;StringHashMap&lt;/code&gt; 也包装了带有字符串特定上下文的 &lt;code&gt;HashMap&lt;/code&gt;。我们将更仔细地看上下文，但这里是 &lt;code&gt;StringHashMap&lt;/code&gt; 使用的上下文：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;StringContext&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Wyhash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;custom-context&quot;&gt;自定义上下文&lt;/h2&gt;&lt;p&gt;我们将在第一部分结束时，直接使用 &lt;code&gt;HashMap&lt;/code&gt;，这意味着提供我们自己的上下文。我们将从一个简单的例子开始：为不区分大小写的 ASCII 字符串创建一个 &lt;code&gt;HashMap&lt;/code&gt;。我们希望以下内容输出：&lt;code&gt;Goku = 9000&lt;/code&gt;。请注意，虽然我们使用键 &lt;code&gt;GOKU&lt;/code&gt; 进行插入，但我们使用“goku”进行获取：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;CaseInsensitiveContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash_map&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;default_max_load_percentage&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;GOKU&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9000&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Goku = {d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;goku&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;与只需要值类型的 &lt;code&gt;StringHashMap&lt;/code&gt; 泛型或需要键和值类型的 &lt;code&gt;AutoHashMap&lt;/code&gt; 不同，&lt;code&gt;HashMap&lt;/code&gt; 需要键类型、值类型、上下文类型和填充因子。我们在此未涉及填充因子；在上面我们使用了 Zig 的默认填充因子（80%）。我们的兴趣点在于 &lt;code&gt;CaseInsensitiveContext&lt;/code&gt; 类型及其实现：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;CaseInsensitiveContext&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;CaseInsensitiveContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Wyhash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lower&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ascii&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;lowerString&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lower&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ascii&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;lowerString&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;final&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;CaseInsensitiveContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ascii&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;eqlIgnoreCase&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这两个函数的第一个参数是上下文本身的实例。这允许更高级的模式，其中上下文可能有状态。但在许多情况下，它并未使用。&lt;/p&gt;&lt;p&gt;我们的 &lt;code&gt;eql&lt;/code&gt; 函数使用现有的 &lt;code&gt;std.ascii.eqlIgnoreCase&lt;/code&gt; 函数以不区分大小写的方式比较两个键。很直观。&lt;/p&gt;&lt;p&gt;我们的 &lt;code&gt;hash&lt;/code&gt; 函数可以分为两部分。第一部分是将键转换为小写。如果我们希望“goku”和“GOKU”被视为相等，我们的哈希函数必须为两者返回相同的哈希码。 我们以 64 字节为一批，以避免分配缓冲区来保存小写值。之所以能做到这一点，是因为我们的散列函数可以使用新字节进行更新（这很常见）。&lt;/p&gt;&lt;p&gt;这引出了第二部分，什么是 &lt;code&gt;std.hash.Wyhash&lt;/code&gt;？当谈到哈希表的哈希算法时（不同于加密哈希算法），我们需要考虑一些属性，例如性能（每次操作哈希表都需要哈希键），均匀分布（如果我们的哈希函数返回 &lt;code&gt;u64&lt;/code&gt;，那么一组随机输入应该在该范围内均匀分布）和碰撞抗性（不同的值可能会产生相同的哈希码，但发生的次数越少越好）。有许多算法，一些专门用于特定输入（例如短字符串），一些专为特定硬件设计。&lt;code&gt;WyHash&lt;/code&gt; 是一种流行的选择，适用于许多输入和特征。你基本上将字节输入，一旦完成，就会得到一个 &lt;code&gt;u64&lt;/code&gt;（或取决于版本的 &lt;code&gt;u32&lt;/code&gt;）。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Teg&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Wyhash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;{d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;final&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Teg&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@intFromError&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;OutOfMemory&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Wyhash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;asBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;{d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;final&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码输出： &lt;code&gt;17623169834704516898&lt;/code&gt;，接着是 &lt;code&gt;7758855794693669122&lt;/code&gt;。这些数字不应该有任何意义。目标只是展示如何将数据输入我们的哈希函数以生成哈希码。&lt;/p&gt;&lt;p&gt;让我们看另一个例子。假设我们有一个 &lt;code&gt;User&lt;/code&gt;，我们希望用它作为哈希表中的键：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们不能使用 &lt;code&gt;AutoHashMap&lt;/code&gt;，因为 &lt;code&gt;name&lt;/code&gt; 不支持切片。示例如下：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;heap&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;GeneralPurposeAllocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gpa&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;HashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;HashContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash_map&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;default_max_load_percentage&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Teg&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Duncan&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;{d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Teg&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;{d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Duncan&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

  &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HashContext&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HashContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HashContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们需要实现 &lt;code&gt;hash&lt;/code&gt; 和 &lt;code&gt;eql&lt;/code&gt; 函数。&lt;code&gt;eql&lt;/code&gt;，通常很直观：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HashContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你看过我们的其他哈希示例，你可能会想到它的实现：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HashContext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Wyhash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;asBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;final&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;插入这两个函数，以上示例应该可以工作。&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot;&gt;结论&lt;/h2&gt;&lt;p&gt;希望你现在对 Zig 的哈希表的实现以及如何在代码中利用它们有了更好的理解。在大多数情况下，&lt;code&gt;std.StringHashMap&lt;/code&gt; 或 &lt;code&gt;std.AutoHashMap&lt;/code&gt; 就足够了。但知道 &lt;code&gt;*Unmanaged&lt;/code&gt; 变体的存在和目的，以及更通用的 &lt;code&gt;std.HashMap&lt;/code&gt;，可能会派上用场。如果没有其他用途，现在文档和它们的实现应该更容易理解了。&lt;/p&gt;&lt;p&gt;在下一部分，我们将深入探讨哈希表的键和值，它们是如何存储和管理的。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;原文地址：&lt;a href=&quot;https://www.openmymind.net/Zigs-HashMap-Part-1/&quot; target=&quot;_blank&quot;&gt;https://www.openmymind.net/Zigs-HashMap-Part-1/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;</description>
        <link>https://ziglang.cc/post/2024-06-10-zig-hashmap-1/</link>
        <pubDate>Mon, 10 Jun 2024 07:57:05 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-06-10-zig-hashmap-1/</guid>
      </item>
    
      <item>
        <title>Zig 标准库中的实现接口的惯用法与模式</title>
        <description>&lt;blockquote&gt;&lt;p&gt;原文链接：&lt;a href=&quot;https://zig.news/yglcode/code-study-interface-idiomspatterns-in-zig-standard-libraries-4lkj&quot; target=&quot;_blank&quot;&gt;https://zig.news/yglcode/code-study-interface-idiomspatterns-in-zig-standard-libraries-4lkj&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;introduction&quot;&gt;引言&lt;/h2&gt;&lt;p&gt;在 Java 和 Go 中，可以使用“接口”（一组方法或方法集）定义基于行为的抽象。通常接口包含所谓的虚表（&lt;code&gt;vtable&lt;/code&gt;） 以实现动态分派。Zig 允许在结构体、枚举、联合和不透明类型中声明函数和方法，尽管 Zig 尚未支持接口作为一种语言特性。 Zig 标准库应用了一些代码习语或模式以达到类似效果。&lt;/p&gt;&lt;p&gt;类似于其他语言中的接口，Zig 的代码习语和模式实现了：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;在编译时对实例/对象方法与接口类型进行类型检查，&lt;/li&gt;&lt;li&gt;在运行时进行动态分派。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;这里有一些显著的不同：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;在 Go 中，接口的定义与实现是独立的。可以在任何位置给一个类型实现新接口，只需保证其方法签名与新接口一致即可。无需像在 Java 中那样，需要回过头去修改类型定义，来实现新的接口。&lt;/li&gt;&lt;li&gt;Go 的接口只包含用于动态分派的 &lt;code&gt;vtab&lt;/code&gt;，并且推荐 vtable 中方法即可能少，例如 &lt;code&gt;io.Reader&lt;/code&gt; 和 &lt;code&gt;io.Writer&lt;/code&gt;只有一个方法。 常见的工具函数如&lt;code&gt;io.Copy&lt;/code&gt;、&lt;code&gt;CopyN&lt;/code&gt;、&lt;code&gt;ReadFull&lt;/code&gt;、&lt;code&gt;ReadAtLeast&lt;/code&gt; 等，作为包函数提供，内部使用这些小接口。 与之相比，Zig 的接口，如 &lt;code&gt;std.mem.Allocator&lt;/code&gt;，同时包含 &lt;code&gt;vtable&lt;/code&gt; 和一些工具方法，因此方法会多一些。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;以下是 Zig 的代码习语/模式在动态分派方面的学习笔记，代码摘自 Zig 标准库并以简单示例重录。为了专注于 vtab/动态分派，工具方法被移除， 代码稍作修改以适应 Go 中不依赖具体类型的“小”接口模式。&lt;/p&gt;&lt;p&gt;完整代码位于&lt;a href=&quot;https://github.com/yglcode/zig_interfaces&quot; target=&quot;_blank&quot;&gt;此仓库&lt;/a&gt;，你可以使用 &lt;code&gt;zig test interfaces.zig&lt;/code&gt; 运行它。&lt;/p&gt;&lt;h2 id=&quot;background-setting&quot;&gt;背景设定&lt;/h2&gt;&lt;p&gt;让我们使用经典的面向对象编程示例，创建一些形状：点（&lt;code&gt;Point&lt;/code&gt;）、盒子（&lt;code&gt;Box&lt;/code&gt;）和圆（&lt;code&gt;Circle&lt;/code&gt;）。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;point@&amp;lt;{d},{d}&amp;gt;&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p2&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;p2&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;center&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;radius&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 创建一组“形状”用于测试&lt;/span&gt;
&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init_data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;point&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;circle&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;interface-1-enumerate-label-unions&quot;&gt;接口 1：枚举标签联合&lt;/h2&gt;&lt;p&gt;Loris Cro 在&lt;a href=&quot;https://zig.news/kristoff/easy-interfaces-with-zig-0100-2hc5&quot; target=&quot;_blank&quot;&gt;“使用 Zig 0.10.0 轻松实现接口”&lt;/a&gt; 中介绍了使用枚举标签联合作为接口的方法。这是最简单的解决方案，尽管你必须在联合类型中显式列出所有“实现”该接口的变体类型。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们可以如下测试：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;union_as_intf&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;init_data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shapes&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;point&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;point&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;circle&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;circle&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shapes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;interface-2-the-first-implementation-of-vtable-and-dynamic-dispatch&quot;&gt;接口 2：vtable 和动态分派的第一种实现&lt;/h2&gt;&lt;p&gt;Zig 已从最初基于嵌入式 &lt;code&gt;vtab&lt;/code&gt; 和 &lt;code&gt;#fieldParentPtr()&lt;/code&gt; 的动态分派切换到基于“胖指针”接口的以下模式； 请查阅此文章了解更多细节&lt;a href=&quot;https://pithlessly.github.io/allocgate.html&quot; target=&quot;_blank&quot;&gt;“Allocgate 将在 Zig 0.9 中到来…”&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;接口 &lt;code&gt;std.mem.Allocator&lt;/code&gt; 使用了这种模式，所有标准分配器，如 &lt;code&gt;std.heap.[ArenaAllocator, GeneralPurposeAllocator, ...]&lt;/code&gt; 都有一个方法 &lt;code&gt;allocator() Allocator&lt;/code&gt; 来暴露这个接口。 以下代码稍作改动，将接口从实现中分离出来。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape2&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 定义接口字段：ptr,vtab&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;//ptr to instance&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtab&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;VTab&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;//ptr to vtab&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;VTab&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 定义封装 vtable 调用的接口方法&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtab&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtab&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 将具体实现类型/对象转换为接口&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape2&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;PtrInfo&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PtrInfo&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必须是指针&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PtrInfo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;One&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必须是单项指针&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PtrInfo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必须指向一个结构体&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;alignment&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PtrInfo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;alignment&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@alignCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;alignment&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@alignCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;alignment&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;vtab&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;draw&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们可以如下测试：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vtab1_as_intf&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;init_data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shapes&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shapes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;interface-3-second-implementation-of-vtable-and-dynamic-dispatch&quot;&gt;接口 3：vtable 和动态分派的第二种实现&lt;/h2&gt;&lt;p&gt;在上述第一种实现中，通过 &lt;code&gt;Shape2.init()&lt;/code&gt; 将 &lt;code&gt;Box&lt;/code&gt; “转换”为接口 &lt;code&gt;Shape2&lt;/code&gt; 时，会对 &lt;code&gt;box&lt;/code&gt; 实例进行类型检查， 以确保其实现了 &lt;code&gt;Shape2&lt;/code&gt; 的方法（包括名称的匹配签名）。第二种实现中有两个变化：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;vtable&lt;/code&gt; 内联在接口结构中（可能的缺点是，接口大小增加）。&lt;/li&gt;&lt;li&gt;需要根据接口进行类型检查的方法被显式地作为函数指针传入，这可能允许传入不同的方法，只要它们具有相同的参数/返回类型。 例如，如果 &lt;code&gt;Box&lt;/code&gt; 有额外的方法，&lt;code&gt;stopAt(i32,i32)&lt;/code&gt; 或甚至 &lt;code&gt;scale(i32,i32)&lt;/code&gt;，我们可以将它们替换为 &lt;code&gt;move()&lt;/code&gt;。 接口 &lt;code&gt;std.rand.Random&lt;/code&gt; 和所有 &lt;code&gt;std.rand.[Pcg, Sfc64, ...]&lt;/code&gt; 使用这种模式。&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape3&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 指向实例的 ptr&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 内联 vtable&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drawFnPtr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;moveFnPtr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;drawFn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;moveFn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape3&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@TypeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必须是指针&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;One&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必须是单项指针&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 必须指向一个结构体&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;alignment&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;alignment&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@alignCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;alignment&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;drawFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;anyopaque&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@ptrCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@alignCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;alignment&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;moveFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drawFnPtr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;moveFnPtr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 定义封装 vtable 函数指针的接口方法&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;drawFnPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;moveFnPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们可以如下测试：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vtab2_as_intf&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;init_data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shapes&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shapes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;interface-4-raw-dynamic-dispatch-using-embedded-vtab-and-fieldparentptr&quot;&gt;接口 4：使用嵌入式 vtab 和 @fieldParentPtr() 的原始动态分派&lt;/h2&gt;&lt;p&gt;接口 &lt;code&gt;std.build.Step&lt;/code&gt; 和所有构建步骤 &lt;code&gt;std.build.[RunStep, FmtStep, ...]&lt;/code&gt; 仍然使用这种模式。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 定义接口/vtab&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drawFn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;moveFn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 定义封装 vtab 函数的接口方法&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;drawFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;moveFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 嵌入 vtab 并将 vtab 函数定义为方法的封装&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle4&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 嵌入 vtab&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle4&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 定义接口封装函数&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@fieldParentPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;shape&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@fieldParentPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;shape&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;center&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;radius&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;shape&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;moveFn&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drawFn&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;draw&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 以下是方法&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;circle@&amp;lt;{d},{d}&amp;gt;radius:{d}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;radius&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 在结构体上直接嵌入 vtab 并定义 vtab 函数&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box4&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 嵌入 vtab&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box4&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p2&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;shape&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;moveFn&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;drawFn&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;draw&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 以下是 vtab 函数，不是方法&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@fieldParentPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;shape&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@fieldParentPtr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;shape&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;box@&amp;lt;{d},{d}&amp;gt;-&amp;lt;{d},{d}&amp;gt;&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们可以如下测试：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vtab3_embedded_in_struct&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;circle&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Circle4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shapes&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Shape4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shapes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;interface-5-compile-time-generic-interface&quot;&gt;接口 5：编译时的泛型接口&lt;/h2&gt;&lt;p&gt;所有上述接口都侧重于 &lt;code&gt;vtab&lt;/code&gt; 和动态分派：接口值将隐藏其持有的具体值的类型。因此，你可以将这些接口值放入数组中并统一处理。&lt;/p&gt;&lt;p&gt;通过 Zig 的编译时计算，你可以定义泛型算法，它可以与提供代码函数体所需的方法或操作符的任何类型一起工作。例如， 我们可以定义一个泛型算法：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;update_graphics&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上所示，“shape”可以是任何类型，只要它提供 &lt;code&gt;move()&lt;/code&gt; 和 &lt;code&gt;draw()&lt;/code&gt; 方法。所有类型检查都发生在编译时，并且没有动态分派。&lt;/p&gt;&lt;p&gt;接下来，我们可以定义一个泛型接口，捕获泛型算法所需的方法；我们可以用它来适应具有不同方法名称的某些类型/实例到所需的 API。&lt;/p&gt;&lt;p&gt;接口 &lt;code&gt;std.io.[Reader, Writer]&lt;/code&gt; 以及 &lt;code&gt;std.fifo&lt;/code&gt; 和 &lt;code&gt;std.fs.File&lt;/code&gt; 使用这种模式。&lt;/p&gt;&lt;p&gt;由于这些泛型接口没有擦除其持有的值的类型信息，它们是不同的类型。因此，你不能将它们放入数组中以统一处理。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Shape5&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;drawFn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;moveFn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Pointer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 封装传入的函数/方法的接口方法&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;drawFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;moveFn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 一种泛型算法使用鸭子类型/静态分派。&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 注意：形状可以是提供 `move()`/`draw()` 的“任何类型”&lt;/span&gt;
&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;update_graphics&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;draw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 定义一个具有相似但不同方法的 `TextArea`&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextArea&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;txt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextArea&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;position&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;txt&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;relocate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextArea&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextArea&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;text@&amp;lt;{d},{d}&amp;gt;:{s}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们可以如下测试：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;generic_interface&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 将泛型算法直接应用于匹配类型&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;update_graphics&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;textarea&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextArea&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;hello zig!&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 使用泛型接口来适应不匹配的类型&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;drawText&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;Shape5&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextArea&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextArea&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextArea&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;relocate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;textarea&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;update_graphics&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;drawText&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
</description>
        <link>https://ziglang.cc/post/2024-05-24-interface-idioms/</link>
        <pubDate>Sat, 25 May 2024 04:21:12 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-05-24-interface-idioms/</guid>
      </item>
    
      <item>
        <title>build.zig.zon 中的依赖项哈希值</title>
        <description>&lt;h2 id=&quot;package-hash&quot;&gt;package hash&lt;/h2&gt;&lt;blockquote&gt;&lt;p&gt;原文地址：&lt;a href=&quot;https://zig.news/michalsieron/buildzigzon-dependency-hashes-47kj&quot; target=&quot;_blank&quot;&gt;build.zig.zon dependency hashes&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;introduction&quot;&gt;引言&lt;/h2&gt;&lt;p&gt;作者 Michał Sieroń 最近在思考 &lt;code&gt;build.zig.zon&lt;/code&gt; 中的依赖项哈希值的问题。这些哈希值都有相同的前缀，而这对加密哈希函数来说极其不同寻常。习惯性使用 Conda 和 Yocto 对下载的压缩包运行 sha256sum，但生成的摘要与 &lt;code&gt;build.zig.zon&lt;/code&gt; 中的哈希值完全不同。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zon&quot;&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dependencies&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mach_freetype&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;https://pkg.machengine.org/mach-freetype/309be0cf11a2f617d06ee5c5bb1a88d5197d8b46.tar.gz&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;1220fcebb0b1a4561f9d116182e30d0a91d2a556dad8564c8f425fd729556dedc7cf&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;font_assets&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;https://github.com/hexops/font-assets/archive/7977df057e855140a207de49039114f1ab8e6c2d.tar.gz&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;12208106eef051bc730bac17c2d10f7e42ea63b579b919480fec86b7c75a620c75d4&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mach_gpu_dawn&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;https://pkg.machengine.org/mach-gpu-dawn/cce4d19945ca6102162b0cbbc546648edb38dc41.tar.gz&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;1220a6e3f4772fed665bb5b1792cf5cff8ac51af42a57ad8d276e394ae19f310a92e&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上摘取自 &lt;a href=&quot;https://github.com/hexops/mach/blob/bffc66800584123e2844c4bc4b577940806f9088/build.zig.zon#L13-L26&quot; target=&quot;_blank&quot;&gt;hexops/mach&lt;/a&gt; 项目。&lt;/p&gt;&lt;h2 id=&quot;preliminary-exploration&quot;&gt;初步探索&lt;/h2&gt;&lt;p&gt;经过一番探索，我找到了一个文档：&lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/doc/build.zig.zon.md&quot; target=&quot;_blank&quot;&gt;doc/build.zig.zon.md&lt;/a&gt;，似乎没有任何线索指向它。而文档中对哈希有段简短的描述。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;哈希&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;类型为字符串。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://multiformats.io/multihash/&quot; target=&quot;_blank&quot;&gt;多重哈希&lt;/a&gt;&lt;/strong&gt; 该哈希值是基于一系列文件内容计算得出的，这些文件是在获取 URL 后并应用了路径规则后得到的。 这个字段是最重要的；一个包是的唯一性是由它的哈希值确定的，不同的 URL 可能对应同一个包。&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;multiple-hashing&quot;&gt;多重哈希&lt;/h2&gt;&lt;p&gt;在他们的网站上有一个很好的可视化展示，说明了这一过程：&lt;a href=&quot;https://multiformats.io/multihash/&quot; target=&quot;_blank&quot;&gt;多重哈希&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ziglang.cc/images/zon-multihash.webp&quot;&gt;
&lt;figcaption&gt;multihash 示意图&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;因此 &lt;code&gt;build.zig.zon&lt;/code&gt; 中的哈希字段不仅包含了摘要 (digest)，还包含了一些元数据 (metadata)。但即使我们丢弃了头部信息，得到的结果仍与下载的 &lt;code&gt;tar&lt;/code&gt; 包的 &lt;code&gt;sha256&lt;/code&gt; 摘要不相符。而这就涉及到了包含规则的问题。&lt;/p&gt;&lt;h2 id=&quot;inclusion-rules&quot;&gt;包含规则 (inclusion rules)&lt;/h2&gt;&lt;p&gt;回到 &lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/doc/build.zig.zon.md&quot; target=&quot;_blank&quot;&gt;doc/build.zig.zon.md&lt;/a&gt; 文件，我们看到：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;这个计算的 hash 结果是在获取 URL 后，根据应用路径给出的包含规则，然后通过获得的文件目录内容计算出来。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;那神秘的包含规则是什么呢？不幸的是，我又没找到这些内容的具体描述。唯一提到这些的地方是在 &lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/src/Package/Fetch.zig#L1-L28&quot; target=&quot;_blank&quot;&gt;ziglang/src/Package/Fetch.zig&lt;/a&gt; 文件的开头，但只能了解到无关文件被过滤后，哈希值是在剩余文件的基础上计算出来的结果。&lt;/p&gt;&lt;p&gt;幸好在代码中快速搜索后，我们找到了负责计算哈希的 &lt;code&gt;fetch&lt;/code&gt; 任务的 &lt;a href=&quot;https://github.com/ziglang/zig/blob/9d64332a5959b4955fe1a1eac793b48932b4a8a8/src/main.zig#L6865&quot; target=&quot;_blank&quot;&gt;主函数&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;我们看到它调用了 &lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/src/Package/Fetch.zig#L478-L485&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;runResource&lt;/code&gt;&lt;/a&gt; 函数。路径字段从依赖的 &lt;code&gt;build.zig.zon&lt;/code&gt; 中读取，并稍后用于创建某种过滤器。&lt;/p&gt;&lt;p&gt;这是我们一直在寻找的过滤器 &lt;code&gt;filter&lt;/code&gt;。在这个结构的命名空间内定义了一个 &lt;code&gt;includePath&lt;/code&gt; 函数，而它处理了所有那些包含规则。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;/// sub_path is relative to the package root.&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;includePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Filter&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;sub_path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;include_paths&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;include_paths&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;include_paths&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;include_paths&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sub_path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Check if any included paths are parent directories of sub_path.&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dirname&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sub_path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;next_dirname&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;include_paths&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;next_dirname&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dirname&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;next_dirname&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个函数用于判断 &lt;code&gt;sub_path&lt;/code&gt; 下的文件是否属于包的一部分。我们可以看到有三种特殊情况，文件会被认为是包的一部分：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;include_paths&lt;/code&gt; 为空&lt;/li&gt;&lt;li&gt;&lt;code&gt;include_paths&lt;/code&gt; 中含有空字符串 “”&lt;/li&gt;&lt;li&gt;&lt;code&gt;include_paths&lt;/code&gt; 包含包的根目录 “.”&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;除此之外，这个函数会检查 &lt;code&gt;sub_path&lt;/code&gt; 是否被明确列出，或者是已明确列出的目录的子目录。&lt;/p&gt;&lt;h2 id=&quot;calculate-the-hash&quot;&gt;计算哈希&lt;/h2&gt;&lt;p&gt;现在我们知道了 &lt;code&gt;build.zig.zon&lt;/code&gt; 的包含规则，也知道使用了 &lt;code&gt;SHA256&lt;/code&gt; 算法。但我们仍然不知道实际的哈希结果是如何得到的。例如，它可能是通过将所有包含的文件内容输入哈希器来计算的。所以让我们再仔细看看，也许我们可以找到答案。&lt;/p&gt;&lt;p&gt;回到 &lt;code&gt;runResource&lt;/code&gt; 函数，我们看到它调用了 &lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/src/Package/Fetch.zig#L1324&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;computeHash&lt;/code&gt;&lt;/a&gt; 函数，这看起来应该是我们感兴趣的主要内容（它顶部的注释已经无人维护，因为这里面会进行&lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/src/Package/Fetch.zig#L1383-L1385&quot; target=&quot;_blank&quot;&gt;文件删除&lt;/a&gt;）。&lt;/p&gt;&lt;p&gt;在其中，我们偶然发现了这段&lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/src/Package/Fetch.zig#L1404-L1416&quot; target=&quot;_blank&quot;&gt;代码&lt;/a&gt;：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HashedFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs_path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fs_path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;normalized_path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;normalizePathAlloc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;arena&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;entry_pkg_path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// to be populated by the worker&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// to be populated by the worker&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
wait_group&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; thread_pool&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;spawn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;workerHashFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;root_dir&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;wait_group&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; all_files&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里没有传递任何哈希对象，只传递了项目的根目录和一个指向 &lt;code&gt;HashedFile&lt;/code&gt; 结构的指针。它有一个专门的 &lt;code&gt;hash&lt;/code&gt; 字段。先前的猜想似乎不成立，因为哈希值是为单个文件存储的。为了更好地理解这个计算过程，顺着这条新线索看看后续。&lt;/p&gt;&lt;p&gt;跟踪 &lt;code&gt;workerHashFile&lt;/code&gt;，我们看到它是 &lt;code&gt;hashFileFallible&lt;/code&gt; 的一个简单包装，而后者看起来相当复杂。让我们来分解一下。&lt;/p&gt;&lt;h2 id=&quot;hash-calculation-for-individual-files&quot;&gt;单个文件的哈希计算&lt;/h2&gt;&lt;p&gt;首先，会进行一些初始化设置，其中创建并用规整后的文件路径初始化了一个新的哈希器实例：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8000&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hasher&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Manifest&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hasher&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;normalized_path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后我们根据我们正在哈希的文件类型进行切换。有两个分支：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;一个用于常规文件&lt;/li&gt;&lt;li&gt;一个用于符号链接&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;首先来看看常规文件的情况：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;openFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs_path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;defer&lt;/span&gt; file&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Hard-coded false executable bit: https://github.com/ziglang/zig/issues/17463&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hasher&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file_header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FileHeader&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes_read&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes_read&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hasher&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes_read&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file_header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes_read&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;首先，打开对应文件文件以便稍后读取其内容，这个符合预期，但紧接着我们放入了两个 null 字节。从阅读 &lt;a href=&quot;https://github.com/ziglang/zig/issues/17463&quot; target=&quot;_blank&quot;&gt;#17463&lt;/a&gt; 来看，这似乎历史原因，为了进行历史兼容。无论如何，之后我们简单地循环读取文件数据的块，并将它们作为数据来计算哈希值。&lt;/p&gt;&lt;p&gt;现在来看看符号链接分支，这个更简单：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;link_name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readLink&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs_path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;canonical_sep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Package hashes are intended to be consistent across&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// platforms which means we must normalize path separators&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// inside symlinks.&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;normalizePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;link_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
hasher&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;link_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;首先进行路径分隔符的规整，保证不同平台一致，之后将符号链接的目标路径输入 &lt;code&gt;hasher&lt;/code&gt;。在 &lt;code&gt;hashFileFallible&lt;/code&gt; 函数最后，把计算出的哈希值赋值给 &lt;code&gt;HashedFile&lt;/code&gt; 对象的 &lt;code&gt;hash&lt;/code&gt; 字段。&lt;/p&gt;&lt;h2 id=&quot;combined-hash&quot;&gt;组合哈希&lt;/h2&gt;&lt;p&gt;尽管有了单个文件的哈希值，但我们仍不知道如何得到最终的哈希。幸运的是，曙光就在眼前。&lt;/p&gt;&lt;p&gt;下一步是确保我们有可复现的结果。 &lt;code&gt;HashedFile&lt;/code&gt; 对象被存储在一个数组中，但文件系统遍历算法可能会改变，所以我们需要对那个数组进行排序。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;sortUnstable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HashedFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_files&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;HashedFile&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;lessThan&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后，我们到达了将所有这些哈希&lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/src/Package/Fetch.zig#L1452-L1464&quot; target=&quot;_blank&quot;&gt;组合成一个的地方&lt;/a&gt;：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hasher&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Manifest&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;any_failures&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_files&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;any_failures&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;eb&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRootErrorMessage&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;eb&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;printString&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;unable to hash &amp;apos;{s}&amp;apos;: {s}&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs_path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@errorName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hasher&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;hashed_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这里我们看到所有计算出的哈希被一个接一个地输入到一个新的哈希器中。在 &lt;code&gt;computeHash&lt;/code&gt; 的最后，我们返回 &lt;code&gt;hasher.finalResult()&lt;/code&gt;，现在我们明白哈希值是如何获得的了。&lt;/p&gt;&lt;h2 id=&quot;final-multiple-hash-value&quot;&gt;最终多哈希值&lt;/h2&gt;&lt;p&gt;现在我们有了一个 &lt;code&gt;SHA256&lt;/code&gt; 摘要，可以最终返回到 &lt;code&gt;main.zig&lt;/code&gt;，在那里我们调用 &lt;a href=&quot;https://github.com/ziglang/zig/blob/9d64332a5959b4955fe1a1eac793b48932b4a8a8/src/Package/Manifest.zig#L174&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;Package.Manifest.hexDigest(fetch.actual_hash)&lt;/code&gt;&lt;/a&gt;。在那里，我们将多哈希头写入缓冲区，之后是我们的组合摘要。&lt;/p&gt;&lt;p&gt;顺便说一下，我们看到所有哈希头都是 &lt;code&gt;1220&lt;/code&gt; 并非巧合。这是因为 &lt;code&gt;Zig&lt;/code&gt; &lt;a href=&quot;https://github.com/ziglang/zig/blob/1a6485d111d270014f57c46c53597a516a24dc47/src/Package/Manifest.zig#L3&quot; target=&quot;_blank&quot;&gt;硬编码了 SHA256&lt;/a&gt; - 0x12，它有 32 字节的摘要 - 0x20。&lt;/p&gt;&lt;h2 id=&quot;summary&quot;&gt;总结&lt;/h2&gt;&lt;p&gt;总结一下：最终哈希值是一个多哈希头 + &lt;code&gt;SHA256&lt;/code&gt; 摘要。&lt;/p&gt;&lt;p&gt;这些摘要是包文件里的部分文件的 &lt;code&gt;SHA256&lt;/code&gt; 摘要。这些摘要根据文件路径排序，并且对于普通文件和符号链接的计算方式不同。&lt;/p&gt;&lt;p&gt;这整个调查实际上是我尝试编写一个输出与 Zig 相同哈希的 shell 脚本的结果。如果你感兴趣，可以在这里阅读它：&lt;a href=&quot;https://gist.github.com/michalsieron/a07da4216d6c5e69b32f2993c61af1b7。&quot; target=&quot;_blank&quot;&gt;https://gist.github.com/michalsieron/a07da4216d6c5e69b32f2993c61af1b7。&lt;/a&gt;&lt;/p&gt;&lt;p&gt;在实验这个之后，我有一个想法，我很惊讶 Zig 没有检查 &lt;code&gt;build.zig.zon&lt;/code&gt; 中列出的所有文件是否存在。但这可能是另一天的话题了。&lt;/p&gt;&lt;h2 id=&quot;translators-note&quot;&gt;译者注&lt;/h2&gt;&lt;p&gt;在使用本地包时，可以使用下面的命令进行 hash 问题的排查：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt; (&lt;span class=&quot;constant function&quot;&gt;main&lt;/span&gt;)&lt;span class=&quot;constant operator function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt; &lt;/span&gt;&lt;span class=&quot;constant property function&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;fetch&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;--debug-hash&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;001f530a93f06d8ad8339ec2f60f17ff9ff0ae29ceaed36942a8bc96ba9d7e26:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;LICENSE&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;ba267af6281ec7b52f90357cdf280e2bf974a0b493314705f18983d4fb818e90:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;b2f7c2d2571a10f289112dbb16599ff88cc9709a7492fe42b76da92b9420ab18:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build.zig.zon&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;614020c9dc5abae8a2a0943030a4e1ddd1ab74a5b40e78896a9db24a353338e1:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;libs/.DS_Store&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;673fd9dc257504fab812c8a7e79ec0cc90f83d426392dc8f1b990149db06e95f:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;libs/curl.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;ebdf40a5c1308661cbaf1d69c3caf439f848e9a506029474f4e4f361e36fc836:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;libs/mbedtls.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;e4e3a40d8e9670984f387936fcdeb9a2cbe86ee70ab898ba3837d922e5c14125:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;libs/zlib.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;6ba4206baa82168198e7c869ce01f002ee7e3cd67c200f5c603fa9c17201333f:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;src/Easy.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;aabb5cedf021c6c7720103dd5e5a2088eeff36823a0ac3303fb965ca16012a8c:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;src/Multi.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;5f254a82524e9d625f7cf2ee80a601da642466d9e7ff764afad480529f51222a:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;src/errors.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;a77c3ca16664533409c4618f54a43f9039427431894d09b03490a91a10864a4c:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;src/root.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;file:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;7b398ebd7ddb3ae30ff1ff1010445b3ed1f252db46608b6a6bd9aace233bc1a4:&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;src/util.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;1220110dc58ece4168ae3b2a0863c8676f8842bbbac763ad30e6ed1e2b68d973d615&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此外，社区已经有人把 multihash 的算法实现独立成一个单独的包，便于计算一个包的 hash 值：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/Calder-Ty/multihash&quot; target=&quot;_blank&quot;&gt;https://github.com/Calder-Ty/multihash&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description>
        <link>https://ziglang.cc/post/2024-05-07-package-hash/</link>
        <pubDate>Tue, 07 May 2024 02:45:10 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-05-07-package-hash/</guid>
      </item>
    
      <item>
        <title>通过 Zig，学习 C++ 元编程</title>
        <description>&lt;p&gt;尽管 Zig 社区宣称 Zig 语言是一个更好的 C (better C)，但是我个人在学习 Zig 语言时经常会”触类旁通”C++。在这里列举一些例子来说明我的一些体会，可能会有一些不正确的地方，欢迎批评指正。&lt;/p&gt;&lt;h2 id=&quot;meta-ability-vs-meta-type&quot;&gt;“元能力” vs “元类型”&lt;/h2&gt;&lt;p&gt;在我看来，C++ 的增强方式是希望赋予语言一种”元能力”，能够让人重新发明新的类型，使得使用 C++ 的程序员使用自定义的类型，进行一种类似于”领域内语言”（DSL）编程。一个通常的说法就是 C++ 中任何类型定义都像是在模仿基本类型&lt;code&gt;int&lt;/code&gt;。比如我们有一种类型 T，那么我们则需要定义 T 在以下几种使用场景的行为：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;type&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;//构造&lt;/span&gt;
&lt;span class=&quot;type&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;//隐式拷贝构造&lt;/span&gt;
&lt;span class=&quot;type&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;x&lt;/span&gt;{&lt;span class=&quot;constant variable&quot;&gt;y&lt;/span&gt;}&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;//显示拷贝构造&lt;/span&gt;
&lt;span class=&quot;constant variable&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;//x 的类型是 T，复制运算符重载，当然也有可能是移动运算符重载。&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;//以及一大堆其他行为，比如析构等等。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过定义各种行为，程序员可以用 C++ 去模拟基础类型&lt;code&gt;int&lt;/code&gt;，自定义的创造新类型。但是 Zig 却采取了另一条路，这里我觉得 Zig 的取舍挺有意思，即它剥夺了程序员定义新类型的能力，只遵循 C 的思路，即&lt;code&gt;struct&lt;/code&gt;就是&lt;code&gt;struct&lt;/code&gt;，他和&lt;code&gt;int&lt;/code&gt;就是不一样的，没有必要通过各种运算符重载来制造一种”幻觉”，模拟&lt;code&gt;int&lt;/code&gt;。相反，Zig 吸收现代语言中最有用的”元类型”，比如&lt;code&gt;slice&lt;/code&gt;，&lt;code&gt;tuple&lt;/code&gt;，&lt;code&gt;tagged union&lt;/code&gt;等作为语言内置的基本类型，从这一点上对 C 进行增强。虽然这样降低了语言的表现力，但是却简化了设计，降低了”心智负担”。&lt;/p&gt;&lt;p&gt;比如 Zig 里的&lt;code&gt;tuple&lt;/code&gt;，C++ 里也有&lt;code&gt;std::tuple&lt;/code&gt;。当然，&lt;code&gt;std::tuple&lt;/code&gt;是通过一系列的模板元编程的方式实现的，但是这个在 Zig 里是内置的，因此写代码时出现语法错误，Zig 可以直接告诉你是&lt;code&gt;tuple&lt;/code&gt;用的不对，但是 C++ 则会打印很多错误日志。再比如&lt;code&gt;optional&lt;/code&gt;，C++ 里也有&lt;code&gt;std::optinonal&amp;lt;T&amp;gt;&lt;/code&gt;，Zig 里只用&lt;code&gt;?T&lt;/code&gt;。C++ 里有&lt;code&gt;std::variant&lt;/code&gt;，而 Zig 里有&lt;code&gt;tagged union&lt;/code&gt;。当然我们可以说，C++ 因为具备了这种元能力，当语法不足够”甜”时，我们可以发明新的轮子，但是代价就是系统愈发的复杂。而 Zig 则持续保持简单。&lt;/p&gt;&lt;p&gt;不过话说回来，很多底层系统的开发需求往往和这种类型系统的构建相悖，比如如果你的类型就是一个&lt;code&gt;int&lt;/code&gt;的封装，那么即使发生拷贝你也无所谓性能开销。但是如果是一个&lt;code&gt;struct&lt;/code&gt;，那么通常情况下，你会比较 care 拷贝，而可能考虑”移动”之类的手段。这个时候各种 C++ 的提供的幻觉，就成了程序员开发的绊脚石，经常你需要分析一段 C++ 表达式里到底有没有发生拷贝，他是左值还是右值，其实你在写 C 语言的时候也很少去考虑了这些，你在 Zig 里同样也不需要。&lt;/p&gt;&lt;h2 id=&quot;type-system&quot;&gt;类型系统&lt;/h2&gt;&lt;p&gt;C 语言最大弊病就是没有提供标准库，C++ 的标准库你要是能看懂，得具备相当的 C++ 的语法知识，但是 Zig 的标准库几乎不需要文档就能看懂。这其实是因为，在 C++ 里，类型不是一等成员 (first class member)，因此实现一些模版元编程算法特别不直观。但是在 Zig 里，&lt;code&gt;type&lt;/code&gt;就是一等成员，比如你可以写：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即，把一个&lt;code&gt;type&lt;/code&gt;当成一个变量使用。但是 C++ 里如何来实现这一行代码呢？其实是如下：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;uint32_t&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那么我们如果要对某个类型做个计算，比如组合一个新类型，Zig 里其实非常直观&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;InputType&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即输入一个类型，输出一个新类型，那么 C++ 里对应的东西是啥呢？&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;InputType&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Some&lt;/span&gt; {
  &lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;OutputType&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;相比之下，Zig 直观太多。那么很自然的，计算一个类型，Zig 里就是调用函数，而 C++ 则是模板类实例化，然后访问类成员。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;type&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;InputType&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;::&lt;span class=&quot;constant variable&quot;&gt;OutputType&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;相当于对于 InputType 调用一个 Some”函数”，然后输出一个 OutputType。&lt;/p&gt;&lt;h2 id=&quot;imperative-vs-declarative&quot;&gt;命令式 VS 声明式&lt;/h2&gt;&lt;p&gt;比如实现一个函数，输入一个 bool 值，根据 bool 值，如果为真，那么输出 type A，如果为假那么输出 type B。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;comment&quot;&gt;//基本模式&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;bool&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;A&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Fn&lt;/span&gt; {
	&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;OutputType&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
}&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;//特例化的模式&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;A&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;false, &lt;span class=&quot;type&quot;&gt;A&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; {
	&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;OutputType&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
}&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从这里 C++ 代码可以感觉出，其实你是拿着尺子，对照着基础模式，然后通过模版偏特化来实现不同分支的逻辑。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;type&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;sizeof&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;A&lt;/span&gt;) &lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;sizeof&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;B&lt;/span&gt;), &lt;span class=&quot;constant variable&quot;&gt;A&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;::&lt;span class=&quot;constant variable&quot;&gt;OutputType&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码表面上看是声明了一个类型 OutputType，而这个类型的生成依赖于一些条件。而这些条件就是模板元编程，用来从 A 和 B 中选择类型大小更大的类型，如果想要表达更复杂的逻辑，则需要掌握更多模板的奇技淫巧。&lt;/p&gt;&lt;p&gt;如果用 Zig 来做，则要简单的多：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码和普通的 &lt;a href=&quot;https://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot; target=&quot;_blank&quot;&gt;CRUD&lt;/a&gt; 逻辑没什么区别，特殊的地方在于操作的对象是『类型』。&lt;/p&gt;&lt;p&gt;我们再来看递归的列子。比如有一个类型的 list，我们需要返回其中第 N 个 type。同样，由于在 C++ 中，类型不是一等成员，因此我们不可能有一个&lt;code&gt;vector&amp;lt;type&amp;gt;&lt;/code&gt;的东东。那怎么办呢？方法就是直接把&lt;code&gt;type list&lt;/code&gt;放在模板的参数列表里：&lt;code&gt;typename ...T&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;于是，我们写出”函数原型”：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;Index&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; ...&lt;span class=&quot;type&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后我们递归的基础情况&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Head&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; ...&lt;span class=&quot;type&quot;&gt;Tail&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;Head&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;Tail&lt;/span&gt;...&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; {
	&lt;span class=&quot;keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Output&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Head&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
}&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后写递归式，&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;Index&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Head&lt;/span&gt;, &lt;span class=&quot;keyword&quot;&gt;typename&lt;/span&gt; ...&lt;span class=&quot;type&quot;&gt;Tail&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;Index&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;Head&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;Tail&lt;/span&gt;...&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt; : &lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Fn&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;constant variable&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;Tail&lt;/span&gt;...&lt;span class=&quot;operator&quot;&gt;&amp;gt;&lt;/span&gt;
{
}&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个地方其实稍微有点难理解，其实就是拿着&lt;code&gt;...T&lt;/code&gt;来模式匹配&lt;code&gt;Head, ...Tail&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;第一个偏特化，如果用命令式，类似于，&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;constant variable&quot;&gt;Index&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;Head&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;第二个偏特化，类似于&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;&lt;span class=&quot;type&quot;&gt;else&lt;/span&gt; {
	&lt;span class=&quot;constant variable&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable function&quot;&gt;Fn&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;Tail&lt;/span&gt;...)&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里利用的其实是继承，让模板推导一路继承下去，如果 Index 不等于 0，那么&lt;code&gt;Fn&amp;lt;Index, ...&amp;gt;&lt;/code&gt;类其实是空类，即，我们无法继承到&lt;code&gt;using Output = ...&lt;/code&gt;的这个&lt;code&gt;Output&lt;/code&gt;。但是 index 总会等于 0，那么到了等于 0 的那天，递归就终止了，因为，我们不需要继续 Index - 1 下去了，编译器会选择特化好的&lt;code&gt;Fn&amp;lt;0, T，Tail...&amp;gt;&lt;/code&gt;这个特化，而不会选择继续递归。&lt;/p&gt;&lt;p&gt;但是 Zig 实现这个也很直观，由于&lt;code&gt;slice&lt;/code&gt;和&lt;code&gt;type&lt;/code&gt;都是内置的，我们可以直接：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;chooseN&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;type_list&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;type_list&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;type_list&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u64&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;{}&lt;/span&gt;&lt;span class=&quot;string string_escape&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;chooseN&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;type_list&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即这个也是完全命令式的。当然 C++20 之后也出现了&lt;code&gt;if constexpr&lt;/code&gt;和&lt;code&gt;concept&lt;/code&gt;来进一步简化模版元编程，C++ 的元编程也在向命令式的方向进化。&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot;&gt;结束语&lt;/h2&gt;&lt;p&gt;尽管 Zig 目前”还不成熟”，但是学习 Zig，如果采用一种对照的思路，偶尔也会”触类旁通”C++，达到举一反三的效果。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2024-04-06-zig-cpp/</link>
        <pubDate>Sat, 06 Apr 2024 11:57:49 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-04-06-zig-cpp/</guid>
      </item>
    
      <item>
        <title>如何发布 Zig 应用程序</title>
        <description>&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;原文链接：&lt;a href=&quot;https://zig.news/kristoff/how-to-release-your-zig-applications-2h90&quot; target=&quot;_blank&quot;&gt;https://zig.news/kristoff/how-to-release-your-zig-applications-2h90&lt;/a&gt;&lt;/li&gt;&lt;li&gt;API 适配到 Zig 0.12.0 版本&lt;/li&gt;&lt;li&gt;本文配套代码在&lt;a href=&quot;https://github.com/zigcc/zigcc.github.io/tree/main/examples/20240112&quot; target=&quot;_blank&quot;&gt;这里&lt;/a&gt;找到&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;You’ve just written an application in Zig and want others to use it. A convenient way for users to use your application is to provide a pre-built executable file. Next, I’ll discuss the two main things that need to be handled correctly in a good release process.&lt;/p&gt;&lt;h2 id=&quot;why-provide-pre-built-executable-files&quot;&gt;Why provide pre-built executable files?&lt;/h2&gt;&lt;p&gt;Given how C/C++ dependencies work (or don’t work), for some C/C++ projects, providing pre-compiled executable files is almost a necessity, otherwise, ordinary people will get stuck in the build system configuration and the number of systems to multiply these by is the number of project dependencies. Using Zig shouldn’t be like this, because Zig build system (plus the upcoming Zig package manager) will be able to handle everything, meaning most well-written applications should just run &lt;code&gt;zig build&lt;/code&gt; to succeed.&lt;/p&gt;&lt;p&gt;That said, the more popular your application is, the less users will care what language it’s written in. Your users don’t want to install Zig and run the build process to easily use your application (99% of the time, the rest 1% will be discussed later), so it’s still better to pre-build your application.&lt;/p&gt;&lt;h2 id=&quot;zig-build-vs-zig-build-exe&quot;&gt;&lt;code&gt;zig build&lt;/code&gt; vs &lt;code&gt;zig build-exe&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;In this article, we’ll see how to make, release a build for a Zig project, so it’s worth spending a little time to fully understand the relationship between Zig build system and command line.&lt;/p&gt;&lt;p&gt;If you have a very simple Zig application (for example, a single file, no dependencies), the simplest way to build a project is to use &lt;code&gt;zig build-exe myapp.zig&lt;/code&gt;, which will create an executable file in the current path.&lt;/p&gt;&lt;p&gt;As the project grows, especially when dependencies start, you might want to add a &lt;code&gt;build.zig&lt;/code&gt; file, and start using Zig build system. Once you start doing this, you can completely control command line parameters to affect the build process.&lt;/p&gt;&lt;p&gt;You can use &lt;code&gt;zig init-exe&lt;/code&gt; to see what a baseline &lt;code&gt;build.zig&lt;/code&gt; file looks like. Note that every line of code in the file is explicitly defined, thus affecting the behavior of &lt;code&gt;zig build&lt;/code&gt; subcommand.&lt;/p&gt;&lt;p&gt;The last thing to note is that although command line parameters will be different when using &lt;code&gt;zig build&lt;/code&gt; and &lt;code&gt;zig build-exe&lt;/code&gt;, in building Zig code, both are equivalent. More specifically, although Zig build can call arbitrary commands, and do other things that may have nothing to do with Zig code, in building Zig code, what &lt;code&gt;zig build&lt;/code&gt; does is to prepare command line parameters for &lt;code&gt;build-exe&lt;/code&gt;. This means that in compiling Zig code, &lt;code&gt;zig build&lt;/code&gt; (assuming the code in &lt;code&gt;build.zig&lt;/code&gt; is correct) and &lt;code&gt;zig build-exe&lt;/code&gt; are one-to-one correspondence. The only difference is convenience.&lt;/p&gt;&lt;h2 id=&quot;build-mode&quot;&gt;Build mode&lt;/h2&gt;&lt;p&gt;When building a Zig project with &lt;code&gt;zig build&lt;/code&gt; or &lt;code&gt;zig build-exe myapp.zig&lt;/code&gt;, the default is a debug build executable file. Debug build is mainly for development convenience, so it’s usually considered unsuitable for release. Debug build aims to sacrifice running performance (running slower) for build speed (compiling faster), soon, Zig compiler will make this trade-off more obvious by introducing incremental compilation and in-place binary patching.&lt;/p&gt;&lt;p&gt;Zig currently has three main release build modes: &lt;code&gt;ReleaseSafe&lt;/code&gt;, &lt;code&gt;ReleaseFast&lt;/code&gt; and &lt;code&gt;ReleaseSmall&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;code&gt;ReleaseSafe&lt;/code&gt; should be considered the main mode to use when releasing: although optimizations are used, it still retains some safety checks (for example, overflow and array bounds), these overheads are absolutely worth it when releasing software that handles uncontrollable input sources (like the internet).&lt;/p&gt;&lt;p&gt;&lt;code&gt;ReleaseFast&lt;/code&gt; is intended for software where performance is the main concern, for example video games. This build mode not only disables the above safety checks, but also assumes that there are no such programming errors in the code.&lt;/p&gt;&lt;p&gt;&lt;code&gt;ReleaseSmall&lt;/code&gt; is similar to &lt;code&gt;ReleaseFast&lt;/code&gt; (i.e., no safety checks), but it’s not prioritized for performance, but rather for trying to minimize the executable file size. For example, this is a very meaningful build mode for WebAssembly, because you want the executable file to be as small as possible, and the sandbox runtime environment has provided a lot of security guarantees.&lt;/p&gt;&lt;h2 id=&quot;how-to-set-build-mode&quot;&gt;How to set build mode&lt;/h2&gt;&lt;p&gt;When using &lt;code&gt;zig build-exe&lt;/code&gt;, you can add &lt;code&gt;-O ReleaseSafe&lt;/code&gt; (or &lt;code&gt;ReleaseFast&lt;/code&gt;, or &lt;code&gt;ReleaseSmall&lt;/code&gt;) to get the corresponding build mode.&lt;/p&gt;&lt;p&gt;When using &lt;code&gt;zig build&lt;/code&gt;, it depends on the configuration of the build script. The default build script will include the following code lines:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// standardReleaseOptions allows us to manually select the target platform and architecture when running zig build&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Default is for this architecture&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// standardOptimizeOption allows us to manually select build mode when running zig build&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Default is Debug&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Standard steps to build a executable binary&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is how you specify release mode in command line: &lt;code&gt;zig build -Doptimize=ReleaseSafe&lt;/code&gt; (or &lt;code&gt;-Doptimize=ReleaseFast&lt;/code&gt;, or &lt;code&gt;-Doptimize=ReleaseSmall&lt;/code&gt;).&lt;/p&gt;&lt;h2 id=&quot;choose-the-correct-build-target&quot;&gt;Choose the correct build target&lt;/h2&gt;&lt;p&gt;Now, we’ve chosen the correct release mode, it’s time to consider build target. Obviously, if the platform used and build platform are different, the corresponding build target needs to be specified, but even if you just intend to release for the same platform, you still need to pay attention.&lt;/p&gt;&lt;p&gt;For convenience, assume you’re using Windows 10 and trying to build an executable file for your friends using Windows 10. The most straightforward way is to directly call &lt;code&gt;zig build&lt;/code&gt; or &lt;code&gt;zig build-exe&lt;/code&gt; (see the difference and similarity between the two commands above), and then send the generated executable file to your friends.&lt;/p&gt;&lt;p&gt;If you do this, sometimes it works, but sometimes it crashes due to &lt;code&gt;illegal instruction&lt;/code&gt; (or similar error). What’s happening?&lt;/p&gt;&lt;h2 id=&quot;cpu-features&quot;&gt;CPU features&lt;/h2&gt;&lt;p&gt;If build target is not specified when building, Zig will build for the current machine, which means it will use all instruction sets supported by the current CPU. If the CPU supports AVX extension, then Zig will use it to perform SIMD operations. But unfortunately, this also means that if your friend’s CPU doesn’t support AVX extension, the application will crash, because this executable file indeed contains illegal instructions.&lt;/p&gt;&lt;p&gt;The simplest way to solve this problem is: always specify a build target when releasing. Yes, if you specify you want to build for &lt;code&gt;x86-64-linux&lt;/code&gt;, Zig will set a baseline CPU that is fully compatible with all CPUs in that series.&lt;/p&gt;&lt;p&gt;If you want to fine-tune instruction set selection, you can check &lt;code&gt;zig build&lt;/code&gt;’s &lt;code&gt;-Dcpu&lt;/code&gt; and &lt;code&gt;zig build-exe&lt;/code&gt;‘s &lt;code&gt;-mcpu&lt;/code&gt;. I won’t cover these details more in this article.&lt;/p&gt;&lt;p&gt;In practice, the following command line will be the build command you’ll use when releasing for Arm macOS:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;$ &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Dtarget&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;aarch64&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;macos&lt;/span&gt;
$ zig build&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; myapp&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; aarch64&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;macos&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that currently &lt;code&gt;=&lt;/code&gt; is required when using &lt;code&gt;zig build&lt;/code&gt;, while it doesn’t work when using &lt;code&gt;build-exe&lt;/code&gt; (i.e., you must put a space between &lt;code&gt;-target&lt;/code&gt; and its value). I hope these weird places will be cleaned up in the near future.&lt;/p&gt;&lt;p&gt;Other related build targets:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;x86&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;linux&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// uses gnu libc&lt;/span&gt;
x86&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;linux&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gnu&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// uses glibc&lt;/span&gt;
x86&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;musl&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// uses musl libc&lt;/span&gt;
x86&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;windows&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// uses MingW headers&lt;/span&gt;
x86&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;windows&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msvc&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// uses MSVC headers but they need to be present in your system&lt;/span&gt;
wasm32&lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;freestanding&lt;/span&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// you will have to use build-obj since wasm modules are not full exes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see the complete list of Zig supported target CPUs and operating systems (as well as libc and instruction sets) by calling &lt;code&gt;zig targets&lt;/code&gt;. Reminder: this is a very long list.&lt;/p&gt;&lt;p&gt;Finally, don’t forget everything in &lt;code&gt;build.zig&lt;/code&gt; must be explicitly defined, so target options can be set through the following code lines:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// standardReleaseOptions allows us to manually select the target platform and architecture when running zig build&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Default is for this architecture&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// standardOptimizeOption allows us to manually select build mode when running zig build&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Default is Debug&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Standard steps to build a executable binary&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This also means if you want to add other restrictions or change how to specify target when building, you can achieve this by adding your own code.&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Now you’ve learned the things you need to ensure correctly when releasing a build: choose a release optimization mode and choose the correct build target, including building for the same system you’re building.&lt;/p&gt;&lt;p&gt;One interesting implication of this last point is that for some of your users (usually 1% on average), it’s actually more beneficial to start building the program from scratch to ensure they make full use of their CPU capabilities.&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2024-01-12-how-to-release-your-zig-applications/</link>
        <pubDate>Fri, 12 Jan 2024 17:04:50 +0000</pubDate>
        <guid>https://ziglang.cc/post/2024-01-12-how-to-release-your-zig-applications/</guid>
      </item>
    
      <item>
        <title>zig 构建系统解析 - 第三部分</title>
        <description>&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;原文链接：&lt;a href=&quot;https://zig.news/xq/zig-build-explained-part-3-1ima&quot; target=&quot;_blank&quot;&gt;https://zig.news/xq/zig-build-explained-part-3-1ima&lt;/a&gt;&lt;/li&gt;&lt;li&gt;API 适配到 Zig 0.11.0 版本&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;从现在起，我将只提供一个最精简的 build.zig，用来说明解决一个问题所需的步骤。如果你想了解如何将所有这些文件粘合到一个构建文件中，请阅读本系列&lt;a href=&quot;https://ziglang.cc/post/2023-12-24-zig-build-explained-part1/&quot;&gt;第一篇文章&lt;/a&gt;。&lt;/p&gt;&lt;h2 id=&quot;composite-project&quot;&gt;复合项目&lt;/h2&gt;&lt;p&gt;有很多简单的项目只包含一个可执行文件。但是，一旦开始编写库，就必须对其进行测试，通常会编写一个或多个示例应用程序。当人们开始使用外部软件包、C 语言库、生成代码等时，复杂性也会随之上升。&lt;/p&gt;&lt;p&gt;本文试图涵盖所有这些用例，并将解释如何使用 build.zig 来编写多个程序和库。&lt;/p&gt;&lt;h2 id=&quot;software-package&quot;&gt;软件包&lt;/h2&gt;&lt;p&gt;译者：此处代码和说明，需要 zig build-exe –pkg-begin，但是在 0.11 已经失效。所以删除。&lt;/p&gt;&lt;h2 id=&quot;library&quot;&gt;库&lt;/h2&gt;&lt;p&gt;但 Zig 也知道库这个词。但我们不是已经讨论过外部库了吗？&lt;/p&gt;&lt;p&gt;在 Zig 的世界里，库是一个预编译的静态或动态库，就像在 C/C++ 的世界里一样。库通常包含头文件（.h 或 .zig）和二进制文件（通常为 .a、.lib、.so 或 .dll）。&lt;/p&gt;&lt;p&gt;这种库的常见例子是 zlib 或 SDL。&lt;/p&gt;&lt;p&gt;与软件包相反，链接库的方式有两种&lt;/p&gt;&lt;ul&gt;&lt;li&gt;(静态库）在命令行中传递文件名&lt;/li&gt;&lt;li&gt;(动态库）使用 -L 将库的文件夹添加到搜索路径中，然后使用 -l 进行实际链接。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;在 Zig 中，我们需要导入库的头文件，如果头文件在 Zig 中，则使用包，如果是 C 语言头文件，则使用 @cImport。&lt;/p&gt;&lt;h2 id=&quot;tool&quot;&gt;工具&lt;/h2&gt;&lt;p&gt;如果我们的项目越来越多，那么在构建过程中就需要使用工具。这些工具通常会完成以下任务：&lt;/p&gt;&lt;p&gt;生成一些代码（如解析器生成器、序列化器或库头文件） 捆绑应用程序（例如生成 APK、捆绑应用程序……）。 创建资产包 … 有了 Zig，我们不仅能在构建过程中利用现有工具，还能为当前主机编译我们自己（甚至外部）的工具并运行它们。&lt;/p&gt;&lt;p&gt;但我们如何在 build.zig 中完成这些工作呢？&lt;/p&gt;&lt;h2 id=&quot;add-pack&quot;&gt;添加软件包&lt;/h2&gt;&lt;p&gt;添加软件包通常使用 LibExeObjStep 上的 addPackage 函数。该函数使用一个 std.build.Pkg 结构来描述软件包的外观：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Module&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;source_file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;StringArrayHashMap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们可以看到，它有 2 个成员：&lt;/p&gt;&lt;p&gt;source_file 是定义软件包根文件的 FileSource。这通常只是指向文件的路径，如 vendor/zig-args/args.zig dependencies 是该软件包所需的可选软件包片段。如果我们使用更复杂的软件包，这通常是必需的。&lt;/p&gt;&lt;p&gt;这是个人建议：我通常会在 build.zig 的顶部创建一个名为 pkgs 的结构/名称空间，看起来有点像这样：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;libs/args/args.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;dependencies&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;libs/interface.zig/interface.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;dependencies&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lola&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/library/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;dependencies&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pkgs&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;lola&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;lola&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;随后通过编译步骤 exe，把模块加入进来。函数 addModule 的第一个参数 name 是模块名称&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;lola&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pkgs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;lola&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
exe&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;args&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pkgs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;add-library&quot;&gt;添加库&lt;/h2&gt;&lt;p&gt;添加库相对容易，但我们需要配置更多的路径。&lt;/p&gt;&lt;p&gt;注：在上一篇文章中，我们已经介绍了大部分内容，但现在还是让我们快速复习一遍：&lt;/p&gt;&lt;p&gt;假设我们要将 libcurl 链接到我们的项目，因为我们要下载一些文件。&lt;/p&gt;&lt;h3 id=&quot;system-library&quot;&gt;系统库&lt;/h3&gt;&lt;p&gt;对于 unixoid 系统，我们通常可以使用系统软件包管理器来链接系统库。方法是调用 linkSystemLibrary，它会使用 pkg-config 自行找出所有路径：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo 3.2&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;curl&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于 Linux 系统，这是链接外部库的首选方式。&lt;/p&gt;&lt;h3 id=&quot;native-library&quot;&gt;本地库&lt;/h3&gt;&lt;p&gt;不过，您也可以链接您作为二进制文件提供商的库。为此，我们需要调用几个函数。首先，让我们来看看这样一个库是什么样子的：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;./vendor/libcurl
include
│ └── curl
│ ├── curl.h
│ ├── curlver.h
│ ├── easy.h
│ ├── mprintf.h
│ ├─── multi.h
│ ├── options.h
│ ├── stdcheaders.h
│ ├── system.h
│ ├── typecheck-gcc.h
│ └── urlapi.h
├── lib
│ ├── libcurl.a
│ ├── libcurl.so
│ └── ...
├─── bin
│ └── ...
└──share
    └── ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们可以看到，vendor/libcurl/include 路径包含我们的头文件，vendor/libcurl/lib 文件夹包含一个静态库（libcurl.a）和一个共享/动态库（libcurl.so）。&lt;/p&gt;&lt;h3 id=&quot;dynamic-link&quot;&gt;动态链接&lt;/h3&gt;&lt;p&gt;要链接 libcurl，我们需要先添加 include 路径，然后向 zig 提供库的前缀和库名：(todo 代码有待验证，因为 curl 可能需要自己编译自己生成 static lib)&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo 3.3&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addIncludePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/include&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addLibraryPath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/lib&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibraryName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;curl&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;addIncludePath 将文件夹添加到搜索路径中，这样 Zig 就能找到 curl/curl.h 文件。注意，我们也可以在这里传递 “vendor/libcurl/include/curl”，但你通常应该检查一下你的库到底想要什么。&lt;/p&gt;&lt;p&gt;addLibraryPath 对库文件也有同样的作用。这意味着 Zig 现在也会搜索 “vendor/libcurl/lib “文件夹中的库。&lt;/p&gt;&lt;p&gt;最后，linkSystemLibrary 会告诉 Zig 搜索名为 “curl “的库。如果你留心观察，就会发现上面列表中的文件名是 libcurl.so，而不是 curl.so。在 unixoid 系统中，库文件的前缀通常是 lib，这样就不会将其传递给系统。在 Windows 系统中，库文件的名字应该是 curl.lib 或类似的名字。&lt;/p&gt;&lt;h2 id=&quot;static-link&quot;&gt;静态链接&lt;/h2&gt;&lt;p&gt;当我们要静态链接一个库时，我们必须采取一些不同的方法：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addIncludeDir&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/include&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
    exe&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addObjectFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/lib/libcurl.a&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
    exe&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addIncludePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/include&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addLibraryPath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/lib&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对 addIncludeDir 的调用没有改变，但我们突然不再调用带 link 的函数了？你可能已经知道了：静态库实际上就是对象文件的集合。在 Windows 上，这一点也很相似，据说 MSVC 也使用了相同的工具集。&lt;/p&gt;&lt;p&gt;因此，静态库就像对象文件一样，通过 addObjectFile 传递给链接器，并由其解包。&lt;/p&gt;&lt;p&gt;注意：大多数静态库都有一些传递依赖关系。在我编译 libcurl 的例子中，就有 nghttp2、zstd、z 和 pthread，我们需要再次手动链接它们：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 示例片段&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addIncludePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/include&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addLibraryPath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/lib&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;nghttp2&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
    exe&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;zstd&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
    exe&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;z&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
    exe&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;pthread&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们可以继续静态链接越来越多的库，并拉入完整的依赖关系树。&lt;/p&gt;&lt;h2 id=&quot;link-library-via-source-code&quot;&gt;通过源代码链接库&lt;/h2&gt;&lt;p&gt;不过，我们还有一种与 Zig 工具链截然不同的链接库方式：&lt;/p&gt;&lt;p&gt;我们可以自己编译它们！&lt;/p&gt;&lt;p&gt;这样做的好处是，我们可以更容易地交叉编译我们的程序。为此，我们需要将库的构建文件转换成我们的 build.zig。这通常需要对 build.zig 和你的库所使用的构建系统都有很好的了解。但让我们假设这个库是超级简单的，只是由一堆 C 文件组成：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 示例片段&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cflags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;；

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; curl &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addSharedLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;curl&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;unversioned&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
    exe&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/src/tool_main.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cflags&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/src/tool_msgs.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cflags&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/src/tool_dirhie.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cflags&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/src/tool_doswin.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cflags&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
    exe&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addIncludePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/include&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;curl&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;；
    b&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样，我们就可以使用 addSharedLibrary 和 addStaticLibrary 向 LibExeObjStep 添加库。&lt;/p&gt;&lt;p&gt;这一点尤其方便，因为我们可以使用 setTarget 和 setBuildMode 从任何地方编译到任何地方。&lt;/p&gt;&lt;h2 id=&quot;use-tooling&quot;&gt;使用工具&lt;/h2&gt;&lt;p&gt;在工作流程中使用工具，通常是在需要以 bison、flex、protobuf 或其他形式进行预编译时。工具的其他用例包括将输出文件转换为不同格式（如固件映像）或捆绑最终应用程序。&lt;/p&gt;&lt;p&gt;系统工具 使用预装的系统工具非常简单，只需使用 addSystemCommand 创建一个新步骤即可：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// demo 3.5&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addSystemCommand&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;flex&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;-outfile=lines.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;lines.l&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从这里可以看出，我们只是向 addSystemCommand 传递了一个选项数组，该数组将反映我们的命令行调用。然后，我们按照习惯创建可执行文件，并使用 dependOn 在 cmd 上添加步骤依赖关系。&lt;/p&gt;&lt;p&gt;我们也可以反其道而行之，在编译程序时添加有关程序的小信息：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo3.6&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addSystemCommand&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;size&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArtifactArg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;size 是一个很好的工具，它可以输出有关可执行文件代码大小的信息，可能如下所示：&lt;/p&gt;&lt;p&gt;文本 数据 BSS Dec 十六进制 文件名 12377 620 104 13101 332d …&lt;/p&gt;&lt;p&gt;如您所见，我们在这里使用了 addArtifactArg，因为 addSystemCommand 只会返回一个 std.build.RunStep。这样，我们就可以增量构建完整的命令行，包括任何 LibExeObjStep 输出、FileSource 或逐字参数。&lt;/p&gt;&lt;h2 id=&quot;new-tools&quot;&gt;全新工具&lt;/h2&gt;&lt;p&gt;最酷的是 我们还可以从 LibExeObjStep 获取 std.build.RunStep：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 示例片段&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;game&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;game&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/game.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;game&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pack_tool&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;pack&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;tools/pack.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;//译者改动：const precompilation = pack_tool.run(); // returns *RunStep&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;precompilation&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pack_tool&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;precompilation&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArtifactArg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;game&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;precompilation&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;assets.zip&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pack_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;pack&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Packs the game and assets together&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pack_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;precompilation&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此构建脚本将首先编译一个名为 pack 的可执行文件。然后将以我们的游戏和 assets.zig 文件作为命令行参数调用该可执行文件。&lt;/p&gt;&lt;p&gt;调用 zig build pack 时，我们将运行 tools/pack.zig。这很酷，因为我们还可以从头开始编译所需的工具。为了获得最佳的开发体验，你甚至可以从源代码编译像 bison 这样的 “外部 “工具，这样就不会依赖系统了！&lt;/p&gt;&lt;h2 id=&quot;putting-everything-together&quot;&gt;将所有内容放在一起&lt;/h2&gt;&lt;p&gt;一开始，所有这些都会让人望而生畏，但如果我们看一个更大的 build.zig 实例，就会发现一个好的构建文件结构会给我们带来很大帮助。&lt;/p&gt;&lt;p&gt;下面的编译脚本将编译一个虚构的工具，它可以通过 flex 生成的词法器解析输入文件，然后使用 curl 连接到服务器，并在那里传送一些文件。当我们调用 zig build deploy 时，项目将被打包成一个 zip 文件。正常的 zig 编译调用只会准备一个未打包的本地调试安装。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 示例片段&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// const mode = b.standardReleaseOptions();&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Generates the lex-based parser&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;parser_gen&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addSystemCommand&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;flex&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;--outfile=review-parser.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;review-parser.l&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Our application&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;upload-review&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;parser_gen&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;review-parser.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// add zig-args to parse arguments&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ap&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;createModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/zig-args/args.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;dependencies&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addModule&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;args-parser&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// add libcurl for uploading&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addIncludePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/include&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addObjectFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/lib/libcurl.a&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// exe.install();&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Our test suite&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Runs the test suite&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_suite&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addTest&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/tests.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_suite&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;parser_gen&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;review-parser.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// add libcurl for uploading&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addIncludePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/include&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addObjectFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;vendor/libcurl/lib/libcurl.a&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_suite&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_suite&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;deploy_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;deploy&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Creates an application bundle&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// compile the app bundler&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;deploy_tool&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;deploy&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;tools/deploy.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;deploy_tool&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;deploy_tool&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;libzip&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bundle_app&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;deploy_tool&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bundle_app&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;app-bundle.zip&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bundle_app&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArtifactArg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bundle_app&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;resources/index.htm&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bundle_app&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;resources/style.css&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;deploy_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bundle_app&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如你所见，代码量很大，但通过使用块，我们可以将构建脚本结构化为逻辑组。&lt;/p&gt;&lt;p&gt;如果你想知道为什么我们不为 deploy_tool 和 test_suite 设置目标： 两者都是为了在主机平台上运行，而不是在目标机器上。 此外，deploy_tool 还设置了固定的编译模式，因为我们希望快速编译，即使我们编译的是应用程序的调试版本。&lt;/p&gt;&lt;h2 id=&quot;summary&quot;&gt;总结&lt;/h2&gt;&lt;p&gt;看完这一大堆文字，你现在应该可以构建任何你想要的项目了。我们已经学会了如何编译 Zig 应用程序，如何为其添加任何类型的外部库，甚至如何为发布管理对应用程序进行后处理。&lt;/p&gt;&lt;p&gt;我们还可以通过少量的工作来构建 C 和 C++ 项目，并将它们部署到各个地方，而不仅仅是 Zig 项目。&lt;/p&gt;&lt;p&gt;即使我们混合使用项目、工具和其他一切。一个 build.zig 文件就能满足我们的需求。但很快你就会发现… 编译文件很快就会重复，而且有些软件包或库需要大量代码才能正确设置。&lt;/p&gt;&lt;p&gt;在下一篇文章中，我们将学习如何将 build.zig 文件模块化，如何为 Zig 创建方便的 sdks，甚至如何创建自己的构建步骤！&lt;/p&gt;&lt;p&gt;一如既往，继续黑客之旅！&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2023-12-29-zig-build-explained-part3/</link>
        <pubDate>Fri, 29 Dec 2023 11:15:02 +0000</pubDate>
        <guid>https://ziglang.cc/post/2023-12-29-zig-build-explained-part3/</guid>
      </item>
    
      <item>
        <title>zig 构建系统解析 - 第二部分</title>
        <description>&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;原文链接：&lt;a href=&quot;https://zig.news/xq/zig-build-explained-part-2-1850&quot; target=&quot;_blank&quot;&gt;https://zig.news/xq/zig-build-explained-part-2-1850&lt;/a&gt;&lt;/li&gt;&lt;li&gt;API 适配到 Zig 0.11.0 版本&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;h2 id=&quot;annotation&quot;&gt;注释&lt;/h2&gt;&lt;p&gt;从现在起，我将只提供一个最精简的 build.zig，用来说明解决一个问题所需的步骤。如果你想了解如何将所有这些文件粘合到一个构建文件中，请阅读本系列&lt;a href=&quot;https://ziglang.cc/post/2023-12-24-zig-build-explained-part1/&quot;&gt;第一篇文章&lt;/a&gt;。&lt;/p&gt;&lt;h2 id=&quot;compile-c-code-on-the-command-line&quot;&gt;在命令行上编译 C 代码&lt;/h2&gt;&lt;p&gt;Zig 有两种编译 C 代码的方法，而且这两种很容易混淆。&lt;/p&gt;&lt;h3 id=&quot;using-zig-cc&quot;&gt;使用 zig cc&lt;/h3&gt;&lt;p&gt;Zig 提供了 LLVM c 编译器 clang。第一种是 zig cc 或 zig c++，它是与 clang 接近 1:1 的前端。由于我们无法直接从 build.zig 访问这些功能（而且我们也不需要！），所以我将在快速的介绍这个主题。&lt;/p&gt;&lt;p&gt;如前所述，zig cc 是暴露的 clang 前端。您可以直接将 CC 变量设置为 zig cc，并使用 zig cc 代替 gcc 或 clang 来使用 Makefiles、CMake 或其他编译系统，这样您就可以在已有的项目中使用 Zig 的完整交叉编译体验。请注意，这只是理论上的说法，因为很多编译系统无法处理编译器名称中的空格。解决这一问题的办法是使用一个简单的封装脚本或工具，将所有参数转发给 zig cc。&lt;/p&gt;&lt;p&gt;假设我们有一个由 main.c 和 buffer.c 生成的项目，我们可以用下面的命令行来构建它：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig cc -o example buffer.c main.c
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这将为我们创建一个名为 example 的可执行文件（在 Windows 系统中，应使用 example.exe 代替 example）。与普通的 clang 不同，Zig 默认会插入一个 -fsanitize=undefined，它将捕捉你使用的未定义行为。&lt;/p&gt;&lt;p&gt;如果不想使用，则必须通过 -fno-sanitize=undefined 或使用优化的发布模式（如 -O2）。&lt;/p&gt;&lt;p&gt;使用 zig cc 进行交叉编译与使用 Zig 本身一样简单：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig cc -o example.exe -target x86_64-windows-gnu buffer.c main.c
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如你所见，只需向 -target 传递目标三元组，就能调用交叉编译。只需确保所有外部库都已准备好进行交叉编译即可！&lt;/p&gt;&lt;h2 id=&quot;use-zig-build-exe-and-other-tools&quot;&gt;使用 zig build-exe 和其他工具&lt;/h2&gt;&lt;p&gt;使用 Zig 工具链构建 C 项目的另一种方法与构建 Zig 项目的方法相同：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig build-exe -lc main.c buffer.c
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里的主要区别在于，必须明确传递 -lc 才能链接到 libc，而且可执行文件的名称将从传递的第一个文件中推导出。如果想使用不同的可执行文件名，可通过 –name example 再次获取示例文件。&lt;/p&gt;&lt;p&gt;交叉编译也是如此，只需通过 -target x86_64-windows-gnu 或其他目标三元组即可：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig build-exe -lc -target x86_64-windows-gnu main.c buffer.c
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;你会发现，使用这条编译命令，Zig 会自动在输出文件中附加 .exe 扩展名，并生成 .pdb 调试数据库。如果你在此处传递 –name example，输出文件也会有正确的 .exe 扩展名，所以你不必考虑这个问题。&lt;/p&gt;&lt;h2 id=&quot;create-c-code-with-buildzig&quot;&gt;用 build.zig 创建 C 代码&lt;/h2&gt;&lt;p&gt;那么，我们如何用 build.zig 来构建上面的两个示例呢？&lt;/p&gt;&lt;p&gt;首先，我们需要创建一个新的编译目标：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;// demo2.1&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 这块调试了很久。最后的结论是根本不要写&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// .root_source_file = .{ .path = undefined },&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 这块调试了很久。API 变了不会写，着了很久的文档和看了很久的代码&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;main.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;buffer.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;//exe.linkLibC();&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后，我们通过 addCSourceFile 添加两个 C 语言文件：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;exe.addCSourceFile(.{ .file = std.build.LazyPath.relative(&amp;quot;main.c&amp;quot;), .flags = &amp;amp;.{} });
exe.addCSourceFile(.{ .file = std.build.LazyPath.relative(&amp;quot;buffer.c&amp;quot;), .flags = &amp;amp;.{} });
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;第一个参数 addCSourceFile 是要添加的 C 或 C++ 文件的名称，第二个参数是该文件要使用的命令行选项列表。&lt;/p&gt;&lt;p&gt;请注意，我们向 addExecutable 传递的是空值，因为我们没有要编译的 Zig 源文件。&lt;/p&gt;&lt;p&gt;现在，调用 zig build 可以正常运行，并在 zig-out/bin 中生成一个可执行文件。很好，我们用 Zig 构建了第一个小 C 项目！&lt;/p&gt;&lt;p&gt;如果你想跳过检查 C 代码中的未定义行为，就必须在调用时添加选项：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;buffer.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;-fno-sanitize=undefined&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;using-external-libraries&quot;&gt;使用外部库&lt;/h2&gt;&lt;p&gt;通常情况下，C 项目依赖于其他库，这些库通常预装在 Unix 系统中，或通过软件包管理器提供。&lt;/p&gt;&lt;p&gt;为了演示这一点，我们创建一个小工具，通过 curl 库下载文件，并将文件内容打印到标准输出：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;c&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;curl/curl.h&amp;gt;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;constant variable function&quot;&gt;writeData&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable&quot;&gt;ptr&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;size&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;nmemb&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;FILE&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable&quot;&gt;stream&lt;/span&gt;) {
    &lt;span class=&quot;type&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;written&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable&quot;&gt;written&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable function&quot;&gt;fwrite&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;ptr&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;size&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;nmemb&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;stream&lt;/span&gt;)&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;written&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
}

&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;constant variable function&quot;&gt;main&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;argc&lt;/span&gt;, &lt;span class=&quot;type&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;argv&lt;/span&gt;)
{
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;argc&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;type&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;argv&lt;/span&gt;[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;]&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;CURL&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable function&quot;&gt;curl_easy_init&lt;/span&gt;()&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;constant variable&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;NULL&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable function&quot;&gt;curl_easy_setopt&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;curl&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;CURLOPT_URL&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;url&lt;/span&gt;)&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable function&quot;&gt;curl_easy_setopt&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;curl&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;CURLOPT_WRITEFUNCTION&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;writeData&lt;/span&gt;)&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable function&quot;&gt;curl_easy_setopt&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;curl&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;CURLOPT_WRITEDATA&lt;/span&gt;, &lt;span class=&quot;constant variable&quot;&gt;stdout&lt;/span&gt;)&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;type&quot;&gt;CURLcode&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable function&quot;&gt;curl_easy_perform&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;curl&lt;/span&gt;)&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable function&quot;&gt;curl_easy_cleanup&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;curl&lt;/span&gt;)&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt;(&lt;span class=&quot;constant variable&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;CURLE_OK&lt;/span&gt;)
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;要编译这个程序，我们需要向编译器提供正确的参数，包括包含路径、库和其他参数。幸运的是，我们可以使用 Zig 内置的 pkg-config 集成：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt; &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// demo2.2&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;downloader&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;download.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;curl&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;让我们创建程序，并通过 URL 调用它&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig build
./zig-out/bin/downloader  https://mq32.de/public/ziggy.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;configuration-path&quot;&gt;配置路径&lt;/h2&gt;&lt;p&gt;由于我们不能在交叉编译项目中使用 pkg-config，或者我们想使用预编译的专用库（如 BASS 音频库），因此我们需要配置包含路径和库路径。&lt;/p&gt;&lt;p&gt;这可以通过函数 addIncludePath 和 addLibraryPath 来完成：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo 2.3&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;bass-player.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 还是一步步看源代码，找新的函数，addIncludeDir,addLibDir -&amp;gt;new function&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addIncludePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;bass/linux&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addLibraryPath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;bass/linux/x64&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkSystemLibrary&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;bass&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;addIncludePath 和 addLibraryPath 都可以被多次调用，以向编译器添加多个路径。这些函数不仅会影响 C 代码，还会影响 Zig 代码，因此 @cImport 可以访问包含路径中的所有头文件。&lt;/p&gt;&lt;h2 id=&quot;include-path-for-each-file&quot;&gt;每个文件的包含路径&lt;/h2&gt;&lt;p&gt;因此，如果我们需要为每个 C 文件设置不同的包含路径，我们就需要用不同的方法来解决这个问题： 由于我们仍然可以通过 addCSourceFile 传递任何 C 编译器标志，因此我们也可以在这里手动设置包含目录。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo2.4&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;multi-main.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;multi.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;-I&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;inc1&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;multi.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;-I&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;inc2&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的示例非常简单，所以你可能会想为什么需要这样的东西。答案是，有些库的头文件名称非常通用，如 api.h 或 buffer.h，而您希望使用两个共享头文件名称的不同库。&lt;/p&gt;&lt;h2 id=&quot;build-c-projects&quot;&gt;构建 C++ 项目&lt;/h2&gt;&lt;p&gt;到目前为止，我们只介绍了 C 文件，但构建 C++ 项目并不难。你仍然可以使用 addCSourceFile，但只需传递一个具有典型 C++ 文件扩展名的文件，如 cpp、cxx、c++ 或 cc：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo2.5&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;main.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;buffer.cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibCpp&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如你所见，我们还需要调用 linkLibCpp，它将链接 Zig 附带的 c++ 标准库。&lt;/p&gt;&lt;p&gt;这就是构建 C++ 文件所需的全部知识，没有什么更神奇的了。&lt;/p&gt;&lt;h2 id=&quot;specify-language-version&quot;&gt;指定语言版本&lt;/h2&gt;&lt;p&gt;试想一下，如果你创建了一个庞大的项目，其中的 C 或 C++ 文件有新有旧，而且可能是用不同的语言标准编写的。为此，我们可以使用编译器标志来传递 -std=c90 或 -std=c++98：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo2.6&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;main.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;-std=c90&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;buffer.cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;-std=c++17&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibCpp&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conditional-compilation&quot;&gt;条件编译&lt;/h2&gt;&lt;p&gt;与 Zig 相比，C 和 C++ 的条件编译方式非常繁琐。由于缺乏惰性求值的功能，有时必须根据目标环境来包含/排除文件。你还必须提供宏定义来启用/禁用某些项目功能。&lt;/p&gt;&lt;p&gt;Zig 编译系统可以轻松处理这两种变体：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo2.7&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;use_platform_io&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;platform-io&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Uses the native api instead of the C wrapper&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;print-main.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;use_platform_io&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;defineCMacro&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;USE_PLATFORM_IO&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;isWindows&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;print-windows.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;print-unix.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过 defineCMacro，我们可以定义自己的宏，就像使用 -D 编译器标志传递宏一样。第一个参数是宏名，第二个值是一个可选项，如果不为空，将设置宏的值。&lt;/p&gt;&lt;p&gt;有条件地包含文件就像使用 if 一样简单，你可以这样做。只要不根据你想在构建脚本中定义的任何约束条件调用 addCSourceFile 即可。只包含特定平台的文件？看看上面的脚本就知道了。根据系统时间包含文件？也许这不是个好主意，但还是有可能的！&lt;/p&gt;&lt;h2 id=&quot;compile-large-projects&quot;&gt;编译大型项目&lt;/h2&gt;&lt;p&gt;由于大多数 C（更糟糕的是 C++）项目都有大量文件（SDL2 有 411 个 C 文件和 40 个 C++ 文件），我们必须找到一种更简单的方法来编译它们。调用 addCSourceFile 400 次并不能很好地扩展。&lt;/p&gt;&lt;p&gt;因此，我们可以做的第一个优化就是将 c 和 c++ 标志放入各自的变量中：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo2.8&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;-Wall&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;-Wextra&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;-Werror=return-type&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cflags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;-std=c99&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cppflags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cflags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;-std=c++17&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;-stdlib=libc++&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;-fno-exceptions&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;main.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cflags&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;buffer.cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;cppflags&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibCpp&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就可以在项目的不同组件和不同语言之间轻松共享标志。&lt;/p&gt;&lt;p&gt;addCSourceFile 还有一个变种，叫做 addCSourceFiles。它使用的不是文件名，而是可编译的所有源文件的文件名片段。这样，我们就可以收集某个文件夹中的所有文件：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo2.9&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sources&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Search for all C/C++ files in `src` and add them&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dir&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;openIterableDir&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;access_sub_paths&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;walker&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;walk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;walker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allowed_exts&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;.cpp&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;.cxx&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;.c++&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;.cc&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;walker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ext&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;extension&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;basename&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;include_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allowed_exts&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ext&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;include_file&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// we have to clone the path as walker.next() or walker.deinit() will override/kill it&lt;/span&gt;
                &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sources&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dupe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFiles&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;sources&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibCpp&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;正如您所看到的，我们可以轻松搜索某个文件夹中的所有文件，匹配文件名并将它们添加到源代码集合中。然后，我们只需为每个文件集调用一次 addCSourceFiles，就可以大展身手了。&lt;/p&gt;&lt;p&gt;你可以制定很好的规则来匹配 exe.target 和文件夹名称，以便只包含通用文件和适合你的平台的文件。不过，这项工作留给读者自己去完成。&lt;/p&gt;&lt;p&gt;注意：其他构建系统会考虑文件名，而 Zig 系统不会！例如，在一个 qmake 项目中不能有两个名为 data.c 的文件！Zig 并不在乎，你可以添加任意多的同名文件，只要确保它们在不同的文件夹中就可以了 😏。&lt;/p&gt;&lt;h2 id=&quot;compiled-objective-c&quot;&gt;编译 Objective C&lt;/h2&gt;&lt;p&gt;我完全忘了！Zig 不仅支持编译 C 和 C++，还支持通过 clang 编译 Objective C！&lt;/p&gt;&lt;p&gt;虽然不支持 C 或 C++，但至少在 macOS 上，你已经可以编译 Objective C 程序并添加框架了：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo2.10&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;main.m&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkFramework&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;Foundation&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这里，链接 libc 是隐式的，因为添加框架会自动强制链接 libc。是不是很酷？&lt;/p&gt;&lt;h2 id=&quot;mixing-c-and-zig-source-code&quot;&gt;混合使用 C 和 Zig 源代码&lt;/h2&gt;&lt;p&gt;现在，是最后一章：混合 C 代码和 Zig 代码！&lt;/p&gt;&lt;p&gt;为此，我们只需将 addExecutable 中的第二个参数设置为文件名，然后点击编译！&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;comment_documentation comment spell&quot;&gt;//demo2.11&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addCSourceFile&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;LazyPath&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;buffer.c&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;linkLibC&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就是需要做的一切！是这样吗？&lt;/p&gt;&lt;p&gt;实际上，有一种情况现在还没有得到很好的支持： 您应用程序的入口点现在必须在 Zig 代码中，因为根文件必须导出一个 pub fn main(…) ……。 因此，如果你想将 C 项目中的代码移植到 Zig 中，你必须将 argc 和 argv 转发到你的 C 代码中，并将 C 代码中的 main 重命名为其他函数（例如 oldMain），然后在 Zig 中调用它。如果需要 argc 和 argv，可以通过 std.process.argsAlloc 获取。或者更好：在 Zig 中重写你的入口点，然后从你的项目中移除一些 C 语言！&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot;&gt;结论&lt;/h2&gt;&lt;p&gt;假设你只编译一个输出文件，那么现在你应该可以将几乎所有的 C/C++ 项目移植到 build.zig。&lt;/p&gt;&lt;p&gt;如果你需要一个以上的构建工件，例如共享库和可执行文件，你应该阅读下一篇文章，它将介绍如何在一个 build.zig 中组合多个项目，以创建便捷的构建体验。&lt;/p&gt;&lt;p&gt;敬请期待！&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2023-12-28-zig-build-explained-part2/</link>
        <pubDate>Sun, 24 Dec 2023 11:15:02 +0000</pubDate>
        <guid>https://ziglang.cc/post/2023-12-28-zig-build-explained-part2/</guid>
      </item>
    
      <item>
        <title>zig 构建系统解析 - 第一部分</title>
        <description>&lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;原文链接：&lt;a href=&quot;https://zig.news/xq/zig-build-explained-part-1-59lf&quot; target=&quot;_blank&quot;&gt;https://zig.news/xq/zig-build-explained-part-1-59lf&lt;/a&gt;&lt;/li&gt;&lt;li&gt;API 适配到 Zig 0.11.0 版本&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;Zig 构建系统仍然缺少文档，对很多人来说，这是不使用它的致命理由。还有一些人经常寻找构建项目的秘诀，但也在与构建系统作斗争。&lt;/p&gt;&lt;p&gt;本系列试图深入介绍构建系统及其使用方法。&lt;/p&gt;&lt;p&gt;我们将从一个刚刚初始化的 Zig 项目开始，逐步深入到更复杂的项目。在此过程中，我们将学习如何使用库和软件包、添加 C 代码，甚至如何创建自己的构建步骤。&lt;/p&gt;&lt;h2 id=&quot;disclaimer&quot;&gt;免责声明&lt;/h2&gt;&lt;p&gt;由于我不会解释 Zig 语言的语法或语义，因此我希望你至少已经有了一些使用 Zig 的基本经验。我还将链接到标准库源代码中的几个要点，以便您了解所有这些内容的来源。我建议你阅读编译系统的源代码，因为如果你开始挖掘编译脚本中的函数，大部分内容都不言自明。所有功能都是在标准库中实现的，不存在隐藏的构建魔法。&lt;/p&gt;&lt;h2 id=&quot;began&quot;&gt;开始&lt;/h2&gt;&lt;p&gt;我们通过新建一个文件夹来创建一个新项目，并在该文件夹中调用 zig init-exe。&lt;/p&gt;&lt;p&gt;这将生成如下 build.zig 文件（我去掉了注释）&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;unit_tests&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addTest&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_unit_tests&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;unit_tests&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run unit tests&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_unit_tests&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;basic-knowledge&quot;&gt;基础知识&lt;/h2&gt;&lt;p&gt;构建系统的核心理念是，Zig 工具链将编译一个 Zig 程序 (build.zig)，该程序将导出一个特殊的入口点（&lt;code&gt;pub fn build(b: *std.build.Builder) void&lt;/code&gt;），当我们调用 &lt;code&gt;zig build&lt;/code&gt; 时，该入口点将被调用。&lt;/p&gt;&lt;p&gt;然后，该函数将创建一个由 std.build.Step 节点组成的有向无环图，其中每个步骤都将执行构建过程的一部分。&lt;/p&gt;&lt;p&gt;每个步骤都有一组依赖关系，这些依赖关系需要在步骤本身完成之前完成。作为用户，我们可以通过调用 &lt;code&gt;zig build ${step-name}&lt;/code&gt; 来调用某些已命名的步骤，或者使用其中一个预定义的步骤（例如 install）。&lt;/p&gt;&lt;p&gt;要创建这样一个步骤，我们需要调用 Builder.step&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;named_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;step-name&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;This is what is shown in help&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;named_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将为我们创建一个新的步骤 step-name，当我们调用 &lt;code&gt;zig build --help&lt;/code&gt; 时将显示该步骤：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant operator function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt; &lt;/span&gt;&lt;span class=&quot;constant property function&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;--help&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;使用方法：&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;[steps]&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;[options］&lt;/span&gt;

&lt;span class=&quot;constant function&quot;&gt;Steps:&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;default&lt;/span&gt;)           &lt;span class=&quot;constant function&quot;&gt;Copy&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;artifacts&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;path&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;uninstall&lt;/span&gt;                   &lt;span class=&quot;constant&quot;&gt;Remove&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;artifacts&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;path&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;step-name&lt;/span&gt;                   &lt;span class=&quot;constant&quot;&gt;This&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;what&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;shown&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;help&lt;/span&gt;

&lt;span class=&quot;constant function&quot;&gt;General&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Options:&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;请注意，除了在 zig build –help 中添加一个小条目并允许我们调用 zig build step-name 之外，这个步骤仍然没有任何作用。&lt;/p&gt;&lt;p&gt;Step 遵循与 std.mem.Allocator 相同的接口模式，需要实现一个 make 函数。步骤创建时将调用该函数。对于我们在这里创建的步骤，该函数什么也不做。&lt;/p&gt;&lt;p&gt;现在，我们需要创建一个稍正式的 Zig 程序：&lt;/p&gt;&lt;h2 id=&quot;compile-zig-source-code&quot;&gt;编译 Zig 源代码&lt;/h2&gt;&lt;p&gt;要使用编译系统编译可执行文件，编译器需要使用函数 Builder.addExecutable，它将为我们创建一个新的 LibExeObjStep。这个步骤实现是 zig build-exe、zig build-lib、zig build-obj 或 zig test 的便捷封装，具体取决于初始化方式。本文稍后将对此进行详细介绍。&lt;/p&gt;&lt;p&gt;现在，让我们创建一个步骤来编译我们的 src/main.zig 文件（之前由 zig init-exe 创建）&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;fresh&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;compile_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;compile&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Compiles src/main.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;compile_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们在这里添加了几行。首先，const exe = b.addExecutable 将创建一个新的 LibExeObjStep，将 src/main.zig 编译成一个名为 fresh 的文件（或 Windows 上的 fresh.exe）。&lt;/p&gt;&lt;p&gt;第二个添加的内容是 compile_step.dependOn(&amp;exe.step);。这就是我们构建依赖关系图的方法，并声明当执行 &lt;code&gt;compile_step&lt;/code&gt; 时，&lt;code&gt;exe&lt;/code&gt; 步骤也需要执行。&lt;/p&gt;&lt;p&gt;你可以调用 zig build，然后再调用 zig build compile 来验证这一点。第一次调用不会做任何事情，但第二次调用会输出一些编译信息。&lt;/p&gt;&lt;p&gt;这将始终在当前机器的调试模式下编译，因此对于初学者来说，这可能就足够了。但如果你想开始发布你的项目，你可能需要启用交叉编译：&lt;/p&gt;&lt;h2 id=&quot;cross-compiling&quot;&gt;交叉编译&lt;/h2&gt;&lt;p&gt;交叉编译是通过设置程序的目标和编译模式来实现的&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;fresh&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ReleaseSafe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;compile_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;compile&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Compiles src/main.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;compile_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这里，&lt;code&gt;.optimize = .ReleaseSafe&lt;/code&gt;, 将向编译调用传递 -O ReleaseSafe。但是！LibExeObjStep.setTarget 需要一个 std.zig.CrossTarget 作为参数，而你通常希望这个参数是可配置的。&lt;/p&gt;&lt;p&gt;幸运的是，构建系统为此提供了两个方便的函数：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Builder.standardReleaseOptions&lt;/li&gt;&lt;li&gt;Builder.standardTargetOptions&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;使用这些函数，可以将编译模式和目标作为命令行选项：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;fresh&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;compile_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;compile&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Compiles src/main.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;compile_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在，如果你调用 zig build –help 命令，就会在输出中看到以下部分，而之前这部分是空的：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;Project-Specific&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Options:&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;-Dtarget=[string]&lt;/span&gt;            &lt;span class=&quot;constant&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;CPU&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;architecture,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;OS,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;ABI&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;for&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;-Dcpu=[string]&lt;/span&gt;               &lt;span class=&quot;constant&quot;&gt;Target&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;CPU&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;features&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;subtract&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;-Doptimize=[enum]&lt;/span&gt;            &lt;span class=&quot;constant&quot;&gt;Prioritize&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;performance,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;safety,&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;binary&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;size&lt;/span&gt; (&lt;span class=&quot;constant function&quot;&gt;-O&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;flag&lt;/span&gt;)
                                &lt;span class=&quot;constant function&quot;&gt;Supported&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;Values:&lt;/span&gt;
                                &lt;span class=&quot;constant function&quot;&gt;Debug&lt;/span&gt;
                                &lt;span class=&quot;constant function&quot;&gt;ReleaseSafe&lt;/span&gt;
                                &lt;span class=&quot;constant function&quot;&gt;ReleaseFast&lt;/span&gt;
                                &lt;span class=&quot;constant function&quot;&gt;ReleaseSmall&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;前两个选项由 standardTargetOptions 添加，其他选项由 standardOptimizeOption 添加。现在，我们可以在调用构建脚本时使用这些选项：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig build -Dtarget=x86_64-windows-gnu -Dcpu=athlon_fx
zig build -Doptimize=ReleaseSafe
zig build -Doptimize=ReleaseSmall
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以看到，对于布尔选项，我们可以省略 =true，直接设置选项本身。&lt;/p&gt;&lt;p&gt;但我们仍然必须调用 zig build 编译，因为默认调用仍然没有任何作用。让我们改变一下！&lt;/p&gt;&lt;h2 id=&quot;installation-artifacts&quot;&gt;安装工件&lt;/h2&gt;&lt;p&gt;要安装任何东西，我们必须让它依赖于构建器的安装步骤。该步骤是已创建的，可通过 Builder.getInstallStep() 访问。我们还需要创建一个新的 InstallArtifactStep，将我们的 exe 文件复制到安装目录（通常是 zig-out）&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;fresh&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;install_exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addInstallArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;install_exe&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将做几件事：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;创建一个新的 InstallArtifactStep，将 exe 的编译结果复制到 $prefix/bin 中。&lt;/li&gt;&lt;li&gt;由于 InstallArtifactStep（隐含地）依赖于 exe，因此它也将编译 exe&lt;/li&gt;&lt;li&gt;当我们调用 zig build install（或简称 zig build）时，它将创建 InstallArtifactStep。&lt;/li&gt;&lt;li&gt;InstallArtifactStep 会将 exe 的输出文件注册到一个列表中，以便再次卸载它&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;现在，当你调用 zig build 时，你会看到一个新的目录 zig-out 被创建了。看起来有点像这样：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig-out
└── bin
    └── fresh
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在运行 ./zig-out/bin/fresh，就能看到这条信息：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;info: All your codebase are belong to us.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或者，你也可以通过调用 zig build uninstall 再次卸载。这将删除 zig build install 创建的所有文件，但不会删除目录！&lt;/p&gt;&lt;p&gt;由于安装过程是一个非常普通的操作，它有快捷方法，以缩短代码。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;fresh&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;installArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你在项目中内置了多个应用程序，你可能会想创建几个单独的安装步骤，并手动依赖它们，而不是直接调用 b.installArtifact(exe);，但通常这样做是正确的。&lt;/p&gt;&lt;p&gt;请注意，我们还可以使用 Builder.installFile（或其他，有很多变体）和 Builder.installDirectory 安装任何其他文件。&lt;/p&gt;&lt;p&gt;现在，从理解初始构建脚本到完全扩展，还缺少一个部分：&lt;/p&gt;&lt;h2 id=&quot;run-the-built-application&quot;&gt;运行已构建的应用程序&lt;/h2&gt;&lt;p&gt;为了开发用户体验和一般便利性，从构建脚本中直接运行程序是非常实用的。这通常是通过运行步骤实现的，可以通过 zig build run 调用。&lt;/p&gt;&lt;p&gt;为此，我们需要一个 RunStep，它将执行我们能在系统上运行的任何可执行文件&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;fresh&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;RunStep 有几个函数可以为执行进程的 argv 添加值：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;addArg 将向 argv 添加一个字符串参数。&lt;/li&gt;&lt;li&gt;addArgs 将同时添加多个字符串参数&lt;/li&gt;&lt;li&gt;addArtifactArg 将向 argv 添加 LibExeObjStep 的结果文件&lt;/li&gt;&lt;li&gt;addFileSourceArg 会将其他步骤生成的任何文件添加到 argv。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;请注意，第一个参数必须是我们要运行的可执行文件的路径。在本例中，我们要运行 exe 的编译输出。&lt;/p&gt;&lt;p&gt;现在，当我们调用 zig build run 时，我们将看到与自己运行已安装的 exe 相同的输出：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;info: All your codebase are belong to us.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;请注意，这里有一个重要的区别：使用 RunStep 时，我们从 ./zig-cache/…/fresh 而不是 zig-out/bin/fresh 运行可执行文件！如果你加载的文件相对于可执行路径，这一点可能很重要。&lt;/p&gt;&lt;p&gt;RunStep 的配置非常灵活，可以通过 stdin 向进程传递数据，也可以通过 stdout 和 stderr 验证输出。你还可以更改工作目录或环境变量。&lt;/p&gt;&lt;p&gt;对了，还有一件事：&lt;/p&gt;&lt;p&gt;如果你想从 zig 编译命令行向进程传递参数，可以通过访问 Builder.args 来实现&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardTargetOptions&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;standardOptimizeOption&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;fresh&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;root_source_file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;src/main.zig&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;optimize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addRunArtifact&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;exe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getInstallStep&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addArgs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;run&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run the app&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;run_cmd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就可以在 cli 上的 – 后面传递参数：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;zig&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;foo.bin&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;foo.asm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;结论&lt;/h2&gt;&lt;p&gt;本系列的第一章应该能让你完全理解本文开头的构建脚本，并能创建自己的构建脚本。&lt;/p&gt;&lt;p&gt;大多数项目甚至只需要编译、安装和运行一些 Zig 可执行文件，所以你就可以开始了！&lt;/p&gt;&lt;p&gt;下一部分我将介绍如何构建 C 和 C++ 项目。&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2023-12-24-zig-build-explained-part1/</link>
        <pubDate>Sun, 24 Dec 2023 11:15:02 +0000</pubDate>
        <guid>https://ziglang.cc/post/2023-12-24-zig-build-explained-part1/</guid>
      </item>
    
      <item>
        <title>Zig 音频之 MIDI —— 源码解读</title>
        <description>&lt;p&gt;MIDI 是”乐器数字接口”的缩写，是一种用于音乐设备之间通信的协议。而 &lt;a href=&quot;https://github.com/Hejsil/zig-midi&quot; target=&quot;_blank&quot;&gt;zig-midi&lt;/a&gt; 主要是在对 MIDI 的元数据、音频头等元数据进行一些处理的方法上进行了集成。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;LICENSE&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;ReadMe.md&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;build.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;example&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│&lt;/span&gt;   &lt;span class=&quot;constant&quot;&gt;└──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;midi_file_to_text_stream.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;midi&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│&lt;/span&gt;   &lt;span class=&quot;constant&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;decode.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│&lt;/span&gt;   &lt;span class=&quot;constant&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;encode.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│&lt;/span&gt;   &lt;span class=&quot;constant&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;file.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;│&lt;/span&gt;   &lt;span class=&quot;constant&quot;&gt;└──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;test.zig&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;├──&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;midi.zig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;basic&quot;&gt;基础&lt;/h2&gt;&lt;p&gt;在 MIDI 协议中，&lt;code&gt;0xFF&lt;/code&gt; 是一个特定的状态字节，用来表示元事件（Meta Event）的开始。元事件是 MIDI 文件结构中的一种特定消息，通常不用于实时音频播放，但它们包含有关 MIDI 序列的元数据，例如序列名称、版权信息、歌词、时间标记、速度（BPM）更改等。&lt;/p&gt;&lt;p&gt;以下是一些常见的元事件类型及其关联的 &lt;code&gt;0xFF&lt;/code&gt;后的字节：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;0x00&lt;/code&gt;: 序列号 (Sequence Number)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x01&lt;/code&gt;: 文本事件 (Text Event)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x02&lt;/code&gt;: 版权通知 (Copyright Notice)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x03&lt;/code&gt;: 序列/曲目名称 (Sequence/Track Name)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x04&lt;/code&gt;: 乐器名称 (Instrument Name)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x05&lt;/code&gt;: 歌词 (Lyric)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x06&lt;/code&gt;: 标记 (Marker)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x07&lt;/code&gt;: 注释 (Cue Point)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x20&lt;/code&gt;: MIDI Channel Prefix&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x21&lt;/code&gt;: End of Track (通常跟随值&lt;code&gt;0x00&lt;/code&gt;，表示轨道的结束)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x2F&lt;/code&gt;: Set Tempo (设定速度，即每分钟的四分音符数)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x51&lt;/code&gt;: SMPTE Offset&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x54&lt;/code&gt;: 拍号 (Time Signature)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x58&lt;/code&gt;: 调号 (Key Signature)&lt;/li&gt;&lt;li&gt;&lt;code&gt;0x59&lt;/code&gt;: Sequencer-Specific Meta-event&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;例如，当解析 MIDI 文件时，如果遇到字节 &lt;code&gt;0xFF 0x03&lt;/code&gt;，那么接下来的字节将表示序列或曲目名称。&lt;/p&gt;&lt;p&gt;在实际的 MIDI 文件中，元事件的具体结构是这样的：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;0xFF&lt;/code&gt;: 元事件状态字节。&lt;/li&gt;&lt;li&gt;元事件类型字节，例如上面列出的 &lt;code&gt;0x00&lt;/code&gt;, &lt;code&gt;0x01&lt;/code&gt; 等。&lt;/li&gt;&lt;li&gt;长度字节（或一系列字节），表示该事件数据的长度。&lt;/li&gt;&lt;li&gt;事件数据本身。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;元事件主要存在于 MIDI 文件中，特别是在标准 MIDI 文件 (SMF) 的上下文中。在实时 MIDI 通信中，元事件通常不会被发送，因为它们通常不会影响音乐的实际播放。&lt;/p&gt;&lt;h2 id=&quot;midizig&quot;&gt;Midi.zig&lt;/h2&gt;&lt;p&gt;本文件主要是处理 MIDI 消息的模块，为处理 MIDI 消息提供了基础结构和函数。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;midi/decode.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;encode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;midi/encode.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;midi/file.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;midi&amp;quot;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;midi/test.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Message&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;_kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;_channel&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x0&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;NoteOff&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x1&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;NoteOn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x2&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;PolyphonicKeyPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x3&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ControlChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x4&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ProgramChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x5&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ChannelPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x6&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;PitchBendChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x7&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_channel&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x0&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ExclusiveStart&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x1&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;MidiTimeCodeQuarterFrame&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x2&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;SongPositionPointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x3&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;SongSelect&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x6&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TuneRequest&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x7&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ExclusiveEnd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x8&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TimingClock&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0xA&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0xB&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Continue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0xC&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0xE&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;ActiveSensing&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0xF&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Reset&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

                &lt;span class=&quot;number&quot;&gt;0x4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x5&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x9&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xD&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u4&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;_channel&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Channel events&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NoteOff&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NoteOn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PolyphonicKeyPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ControlChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ProgramChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ChannelPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PitchBendChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_channel&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

            &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// System events&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveStart&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiTimeCodeQuarterFrame&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SongPositionPointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SongSelect&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TuneRequest&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveEnd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TimingClock&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Continue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ActiveSensing&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Reset&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Undefined&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u14&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO: Is this the right order according to the midi spec?&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u14&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;setValue&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u14&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Channel events&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NoteOff&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NoteOn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PolyphonicKeyPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ControlChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ProgramChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ChannelPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PitchBendChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// System events&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveStart&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiTimeCodeQuarterFrame&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SongPositionPointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SongSelect&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TuneRequest&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveEnd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TimingClock&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Continue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ActiveSensing&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Reset&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这定义了一个名为 Message 的公共结构，表示 MIDI 消息，为处理 MIDI 消息提供了基础结构和函数。它包含三个字段：状态、值和几个公共方法。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;kind 函数：根据 MIDI 消息的状态码确定消息的种类。&lt;/li&gt;&lt;li&gt;channel 函数：根据消息的种类返回 MIDI 通道，如果消息不包含通道信息则返回 null。&lt;/li&gt;&lt;li&gt;value 和 setValue 函数：用于获取和设置 MIDI 消息的值字段。&lt;/li&gt;&lt;li&gt;Kind 枚举：定义了 MIDI 消息的所有可能种类，包括通道事件和系统事件。&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;midi-message-structure&quot;&gt;midi 消息结构&lt;/h3&gt;&lt;p&gt;我们需要先了解 MIDI 消息的一些背景。&lt;/p&gt;&lt;p&gt;在 MIDI 协议中，某些消息的值可以跨越两个 7 位的字节，这是因为 MIDI 协议不使用每个字节的最高位（这通常被称为状态位）。这意味着每个字节只使用它的低 7 位来携带数据。因此，当需要发送一个大于 7 位的值时（比如 14 位），它会被拆分成两个 7 位的字节。&lt;/p&gt;&lt;p&gt;&lt;code&gt;setValue&lt;/code&gt; 这个函数做的事情是将一个 14 位的值（&lt;code&gt;u14&lt;/code&gt;）拆分为两个 7 位的值，并将它们设置到 &lt;code&gt;message.values&lt;/code&gt; 中。&lt;/p&gt;&lt;p&gt;以下是具体步骤的解释：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;获取高 7 位&lt;/strong&gt;：&lt;code&gt;v &amp;gt;&amp;gt; 7&lt;/code&gt; 把 14 位的值右移 7 位，这样我们就得到了高 7 位的值。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;截断并转换&lt;/strong&gt;：&lt;code&gt;@truncate(v &amp;gt;&amp;gt; 7)&lt;/code&gt; 截断高 7 位的值，确保它是 7 位的。&lt;code&gt;@as(u7, @truncate(v &amp;gt;&amp;gt; 7))&lt;/code&gt; 确保这个值是 &lt;code&gt;u7&lt;/code&gt; 类型，即一个 7 位的无符号整数。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;获取低 7 位&lt;/strong&gt;：&lt;code&gt;@truncate(v)&lt;/code&gt; 直接截断原始值，保留低 7 位。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;设置值&lt;/strong&gt;：&lt;code&gt;message.values = .{ ... }&lt;/code&gt; 将这两个 7 位的值设置到 &lt;code&gt;message.values&lt;/code&gt; 中。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 id=&quot;event&quot;&gt;事件&lt;/h3&gt;&lt;p&gt;针对事件，我们看 enum。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Channel events&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NoteOff&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NoteOn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PolyphonicKeyPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ControlChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ProgramChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ChannelPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PitchBendChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// System events&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveStart&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiTimeCodeQuarterFrame&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SongPositionPointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SongSelect&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TuneRequest&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveEnd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TimingClock&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Continue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ActiveSensing&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Reset&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码定义了一个名为 &lt;code&gt;Kind&lt;/code&gt; 的公共枚举类型（&lt;code&gt;enum&lt;/code&gt;），它描述了 MIDI 中可能的事件种类。每个枚举成员都代表 MIDI 协议中的一个特定事件。这些事件分为两大类：频道事件（Channel events）和系统事件（System events）。&lt;/p&gt;&lt;p&gt;这个 &lt;code&gt;Kind&lt;/code&gt; 枚举为处理 MIDI 消息提供了一个结构化的方法，使得在编程时可以清晰地引用特定的 MIDI 事件，而不是依赖于原始的数字或其他编码。&lt;/p&gt;&lt;p&gt;以下是对每个枚举成员的简要说明：&lt;/p&gt;&lt;h4 id=&quot;channel-events&quot;&gt;频道事件 (Channel events)&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;NoteOff&lt;/strong&gt;：这是一个音符结束事件，表示某个音符不再播放。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;NoteOn&lt;/strong&gt;：这是一个音符开始事件，表示开始播放某个音符。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;PolyphonicKeyPressure&lt;/strong&gt;：多声道键盘压力事件，表示对特定音符的压力或触摸敏感度的变化。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ControlChange&lt;/strong&gt;：控制变更事件，用于发送如音量、平衡等控制信号。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ProgramChange&lt;/strong&gt;：程序（音色）变更事件，用于改变乐器的音色。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ChannelPressure&lt;/strong&gt;：频道压力事件，与多声道键盘压力相似，但它适用于整个频道，而不是特定音符。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;PitchBendChange&lt;/strong&gt;：音高弯曲变更事件，表示音符音高的上升或下降。&lt;/li&gt;&lt;/ol&gt;&lt;h4 id=&quot;system-events&quot;&gt;系统事件 (System events)&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;ExclusiveStart&lt;/strong&gt;：独占开始事件，标志着一个独占消息序列的开始。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;MidiTimeCodeQuarterFrame&lt;/strong&gt;：MIDI 时间码四分之一帧，用于同步与其他设备。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;SongPositionPointer&lt;/strong&gt;：歌曲位置指针，指示序列器的当前播放位置。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;SongSelect&lt;/strong&gt;：歌曲选择事件，用于选择特定的歌曲或序列。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;TuneRequest&lt;/strong&gt;：调音请求事件，指示设备应进行自我调音。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ExclusiveEnd&lt;/strong&gt;：独占结束事件，标志着一个独占消息序列的结束。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;TimingClock&lt;/strong&gt;：计时时钟事件，用于节奏的同步。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Start&lt;/strong&gt;：开始事件，用于启动序列播放。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Continue&lt;/strong&gt;：继续事件，用于继续暂停的序列播放。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Stop&lt;/strong&gt;：停止事件，用于停止序列播放。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ActiveSensing&lt;/strong&gt;：活动感知事件，是一种心跳信号，表示设备仍然在线并工作。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reset&lt;/strong&gt;：重置事件，用于将设备重置为其初始状态。&lt;/li&gt;&lt;/ol&gt;&lt;h4 id=&quot;other&quot;&gt;其他&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Undefined&lt;/strong&gt;：未定义事件，可能表示一个未在此枚举中定义的或无效的 MIDI 事件。&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;decodezig&quot;&gt;decode.zig&lt;/h2&gt;&lt;p&gt;本文件是对 MIDI 文件的解码器，提供了一组工具，可以从不同的输入源解析 MIDI 文件的各个部分。这样可以方便地读取和处理 MIDI 文件。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;../midi.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;math&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;statusByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;readDataByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidDataByte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;last_message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;statusByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidMessage&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidMessage&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;channel&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;number&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x6&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidDataByte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;readDataByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;number&quot;&gt;0x4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x5&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;orelse&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidDataByte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;number&quot;&gt;0x7&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x6&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x07&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xA&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xB&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xC&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xE&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xF&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x3&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;readDataByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x2&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;readDataByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;readDataByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

                &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// Undefined&lt;/span&gt;
                &lt;span class=&quot;number&quot;&gt;0x4&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x5&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0x9&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xD&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Chunk&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readNoEof&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;chunkFromBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;chunkFromBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Chunk&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Chunk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readIntBig&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;fileHeader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Header&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readNoEof&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fileHeaderFromBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;fileHeaderFromBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Header&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_chunk&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;chunkFromBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;eql&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file_header&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidFileHeader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidFileHeader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readIntBig&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;tracks&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readIntBig&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readIntBig&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u28&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u28&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_last&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;mul&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u28&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;maxInt&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u28&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_last&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;metaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;MetaEvent&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;MetaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;trackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TrackEvent&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;peek_reader&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;peekStream&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;in_reader&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;peek_reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;delta_time&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;in_reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;in_reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;delta_time&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;delta_time&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;MetaEvent&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;metaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;in_reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_midi_event&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiEvent&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MetaEvent&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;peek_reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;putBackByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;unreachable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;delta_time&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;delta_time&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;MidiEvent&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;in_reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_midi_event&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment_documentation comment spell&quot;&gt;/// Decodes a midi file from a reader. Caller owns the returned value&lt;/span&gt;
&lt;span class=&quot;comment_documentation comment spell&quot;&gt;///  (see: `midi.File.deinit`).&lt;/span&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunks&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;FileChunk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;errdefer&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunks&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;toOwnedSlice&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fileHeader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header_data&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;errdefer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header_data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readNoEof&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header_data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;EndOfStream&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunk_bytes&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;errdefer&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunk_bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readNoEof&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunk_bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunk_bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;header_data&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header_data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunks&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;toOwnedSlice&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;&lt;li&gt;statusByte: 解析 MIDI 消息的首个字节，来确定是否这是一个状态字节，还是一个数据字节。将一个字节 b 解码为一个 u7 类型的 MIDI 状态字节，如果字节 b 不是一个状态字节，则返回 null。换句话说，midi 的消息是 14 位，如果高 7 位不为空，则是 midi 消息的状态字节。在 MIDI 协议中，消息的首个字节通常是状态字节，但也可能用之前的状态字节（这称为”运行状态”）来解释接下来的字节。因此，这段代码需要确定它是否读取了一个新的状态字节，或者它是否应该使用前一个消息的状态字节。&lt;/li&gt;&lt;li&gt;readDataByte: 从 reader 中读取并返回一个数据字节。如果读取的字节不符合数据字节的规定，则抛出 InvalidDataByte 错误。&lt;/li&gt;&lt;li&gt;message: 从 reader 读取并解码一个 MIDI 消息。如果读取的字节不能形成一个有效的 MIDI 消息，则抛出 InvalidMessage 错误。这是一个复杂的函数，涉及到解析 MIDI 消息的不同种类。&lt;/li&gt;&lt;li&gt;chunk，chunkFromBytes: 这两个函数从 reader 或直接从字节数组 bytes 中解析一个 MIDI 文件块头。&lt;/li&gt;&lt;li&gt;fileHeader, fileHeaderFromBytes: 这两个函数从 reader 或直接从字节数组 bytes 中解析一个 MIDI 文件头。&lt;/li&gt;&lt;li&gt;int: 从 reader 中解码一个可变长度的整数。&lt;/li&gt;&lt;li&gt;metaEvent: 从 reader 中解析一个 MIDI 元事件。&lt;/li&gt;&lt;li&gt;trackEvent: 从 reader 中解析一个 MIDI 轨道事件。它可以是 MIDI 消息或元事件。&lt;/li&gt;&lt;li&gt;file: 用于从 reader 解码一个完整的 MIDI 文件。它首先解码文件头，然后解码所有的文件块。这个函数会返回一个表示 MIDI 文件的结构体。&lt;/li&gt;&lt;/ol&gt;&lt;h3 id=&quot;message-analysis&quot;&gt;message 解析&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;statusByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;first_byte&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;status_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidMessage&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InvalidMessage&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码的目的是确定 MIDI 消息的状态字节。它可以是从 &lt;code&gt;reader&lt;/code&gt; 读取的当前字节，或者是从前一个 MIDI 消息中获取的。这样做是为了支持 MIDI 协议中的”运行状态”，在该协议中，连续的 MIDI 消息可能不会重复状态字节。&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;const status_byte = ...;&lt;/code&gt;: 这是一个常量声明。&lt;code&gt;status_byte&lt;/code&gt; 将保存 MIDI 消息的状态字节。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;if (statusByte(first_byte.?)) |status_byte| blk: { ... }&lt;/code&gt;:&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;statusByte(first_byte.?)&lt;/code&gt;: 这是一个函数调用，它检查 &lt;code&gt;first_byte&lt;/code&gt; 是否是一个有效的状态字节。&lt;code&gt;.?&lt;/code&gt; 是可选值的语法，它用于解包 &lt;code&gt;first_byte&lt;/code&gt; 的值（它是一个可选的 &lt;code&gt;u8&lt;/code&gt;，可以是 &lt;code&gt;u8&lt;/code&gt; 或 &lt;code&gt;null&lt;/code&gt;）。&lt;/li&gt;&lt;li&gt;&lt;code&gt;|status_byte|&lt;/code&gt;: 如果 &lt;code&gt;statusByte&lt;/code&gt; 函数返回一个有效的状态字节，则这个值会被捕获并赋给这里的 &lt;code&gt;status_byte&lt;/code&gt; 变量。&lt;/li&gt;&lt;li&gt;&lt;code&gt;blk:&lt;/code&gt;: 这是一个匿名代码块的标签。Zig 允许你给代码块命名，这样你可以从该代码块中跳出。&lt;/li&gt;&lt;li&gt;&lt;code&gt;{ ... }&lt;/code&gt;: 这是一个代码块。在这里，&lt;code&gt;first_byte&lt;/code&gt; 被设置为 &lt;code&gt;null&lt;/code&gt;，然后使用 &lt;code&gt;break :blk status_byte;&lt;/code&gt; 来结束此代码块，并将 &lt;code&gt;status_byte&lt;/code&gt; 的值赋给外部的 &lt;code&gt;status_byte&lt;/code&gt; 常量。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;else if (last_message) |m| blk: { ... }&lt;/code&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;如果 &lt;code&gt;first_byte&lt;/code&gt; 不是一个状态字节，代码会检查是否存在一个名为 &lt;code&gt;last_message&lt;/code&gt; 的前一个 MIDI 消息。&lt;/li&gt;&lt;li&gt;&lt;code&gt;|m|&lt;/code&gt;: 如果 &lt;code&gt;last_message&lt;/code&gt; 存在（即它不是 &lt;code&gt;null&lt;/code&gt;），它的值将被捕获并赋给 &lt;code&gt;m&lt;/code&gt;。&lt;/li&gt;&lt;li&gt;&lt;code&gt;{ ... }&lt;/code&gt;: 这是另一个代码块。在这里，它检查 &lt;code&gt;m&lt;/code&gt; 是否有一个通道。如果没有，则返回一个 &lt;code&gt;InvalidMessage&lt;/code&gt; 错误。否则，使用 &lt;code&gt;break :blk m.status;&lt;/code&gt; 结束此代码块，并将 &lt;code&gt;m.status&lt;/code&gt; 的值赋给外部的 &lt;code&gt;status_byte&lt;/code&gt; 常量。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;else return error.InvalidMessage;&lt;/code&gt;: 如果 &lt;code&gt;first_byte&lt;/code&gt; 不是状态字节，并且不存在前一个消息，那么返回一个 &lt;code&gt;InvalidMessage&lt;/code&gt; 错误。&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;encodezig&quot;&gt;encode.zig&lt;/h2&gt;&lt;p&gt;本文件用于将 MIDI 数据结构编码为其对应的二进制形式。具体来说，它是将内存中的 MIDI 数据结构转换为 MIDI 文件格式的二进制数据。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;../midi.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;math&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;encode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@This&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;last_message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;channel&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_message&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_message&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.?&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveStart&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TuneRequest&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveEnd&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TimingClock&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Continue&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ActiveSensing&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Reset&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ProgramChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ChannelPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiTimeCodeQuarterFrame&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SongSelect&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NoteOff&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;NoteOn&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PolyphonicKeyPressure&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ControlChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;PitchBendChange&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SongPositionPointer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;chunkToBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;_chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Chunk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeIntBig&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;fileHeaderToBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;chunkToBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeIntBig&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeIntBig&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;tracks&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeIntBig&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u28&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_first&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fixedBufferStream&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO: Can we find a way to not encode this in reverse order and then flipping the bytes?&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_first&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_first&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@intFromBool&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_first&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt;
            &lt;span class=&quot;constant_builtin&quot;&gt;unreachable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getWritten&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getWritten&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;metaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;MetaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind_byte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;trackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_midi_event&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiEvent&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MetaEvent&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;delta_time&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MetaEvent&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;metaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiEvent&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;last_midi_event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fileHeaderToBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file_header&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@intCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;header_data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;tracks&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@intCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;header_data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;chunkToBytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@intCast&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;&lt;li&gt;&lt;p&gt;message 函数：这是将 MIDI 消息编码为字节序列的函数，将单个 MIDI 消息编码为其二进制形式。根据消息类型，这会向提供的 writer 写入一个或多个字节。若消息需要状态字节，并且不同于前一个消息的状态，函数会写入状态字节。接着，根据消息的种类，函数会写入所需的数据字节。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;chunkToBytes 函数：将 MIDI 文件的块（Chunk）信息转换为 8 字节的二进制数据。这 8 字节中包括 4 字节的块类型和 4 字节的块长度。它复制块类型到前 4 个字节，然后写入块的长度到后 4 个字节，并返回结果。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;fileHeaderToBytes 函数：编码 MIDI 文件的头部为 14 字节的二进制数据。这 14 字节包括块信息、文件格式、轨道数量和时间划分信息。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;int 函数：将一个整数编码为 MIDI 文件中的可变长度整数格式。在 MIDI 文件中，某些整数值使用一种特殊的编码格式，可以根据整数的大小变化长度。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;metaEvent 函数：将 MIDI 元事件（Meta Event）编码为二进制数据，这包括事件的类型和长度。具体则是编码一个元事件，首先写入其种类字节，然后是其长度。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;trackEvent 函数：编码轨道事件。轨道事件可以是元事件或 MIDI 事件，函数首先写入事件之间的时间差（delta 时间），然后根据事件类型（MetaEvent 或 MidiEvent）编码事件内容。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;file 函数：这是主函数，用于将整个 MIDI 文件数据结构编码为其二进制形式。它首先编码文件头，然后循环编码每个块和块中的事件。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;int-function&quot;&gt;int 函数&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;
&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;anytype&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u28&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_first&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fixedBufferStream&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;buf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// TODO: Can we find a way to not encode this in reverse order and then flipping the bytes?&lt;/span&gt;
    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;keyword_operator&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_first&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_first&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@truncate&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tmp&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@as&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@intFromBool&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;is_first&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt;
            &lt;span class=&quot;constant_builtin&quot;&gt;unreachable&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tmp&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getWritten&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;writeAll&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;fbs&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;getWritten&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个函数&lt;code&gt;int&lt;/code&gt;用于编码一个整数为 MIDI 文件中的可变长度整数格式。在 MIDI 文件中，许多值（如 delta 时间）使用这种可变长度编码。&lt;/p&gt;&lt;p&gt;详细地解析这个函数的每一步：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;参数定义&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;writer&lt;/code&gt;: 任意类型的写入对象，通常是一种流或缓冲区，可以向其写入数据。&lt;/li&gt;&lt;li&gt;&lt;code&gt;i&lt;/code&gt;: 一个最多 28 位的无符号整数（&lt;code&gt;u28&lt;/code&gt;），即要编码的值。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;局部变量初始化&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;tmp&lt;/code&gt;：作为输入整数的临时副本。&lt;/li&gt;&lt;li&gt;&lt;code&gt;is_first&lt;/code&gt;：一个布尔值，用于指示当前处理的是否是整数的第一个字节。&lt;/li&gt;&lt;li&gt;&lt;code&gt;buf&lt;/code&gt;: 定义一个 4 字节的缓冲区。因为最大的&lt;code&gt;u28&lt;/code&gt;值需要 4 个字节的可变长度编码。&lt;/li&gt;&lt;li&gt;&lt;code&gt;fbs&lt;/code&gt;：使用&lt;code&gt;io.fixedBufferStream&lt;/code&gt;创建一个固定缓冲区的流，并获取它的写入器。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;循环进行可变长度编码&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;循环条件是：直到&lt;code&gt;tmp&lt;/code&gt;为 0 并且不是第一个字节。&lt;/li&gt;&lt;li&gt;&lt;code&gt;: (is_first = false)&lt;/code&gt; 是一个后置条件，每次循环结束后都会执行。&lt;/li&gt;&lt;li&gt;&lt;code&gt;(@as(u8, 1 &amp;lt;&amp;lt; 7) * @intFromBool(!is_first))&lt;/code&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;1 &amp;lt;&amp;lt; 7&lt;/code&gt;: 这个操作是左移操作。数字 1 在二进制中表示为&lt;code&gt;0000 0001&lt;/code&gt;。当你将它左移 7 位时，你得到&lt;code&gt;1000 0000&lt;/code&gt;，这在十进制中等于 &lt;code&gt;128&lt;/code&gt;。&lt;/li&gt;&lt;li&gt;&lt;code&gt;@intFromBool(!is_first)&lt;/code&gt;: 这是将上一步得到的布尔值转换为整数。在许多编程语言中，true 通常被视为 1，false 被视为 0。在 Zig 中，这种转换不是隐式的，所以需要用&lt;code&gt;@intFromBool()&lt;/code&gt;函数来进行转换&lt;/li&gt;&lt;li&gt;&lt;code&gt;@as(u8, 1 &amp;lt;&amp;lt; 7)&lt;/code&gt;: 这里是将数字 128（从 1 &lt;&lt; 7 得到）显式地转换为一个 8 位无符号整数。&lt;/li&gt;&lt;li&gt;&lt;code&gt;(@as(u8, 1 &amp;lt;&amp;lt; 7) * @intFromBool(!is_first))&lt;/code&gt;: 将转换后的数字 128 与从布尔转换得到的整数（0 或 1）相乘。如果&lt;code&gt;is_first&lt;/code&gt;为&lt;code&gt;true&lt;/code&gt;（即这是第一个字节），那么整个表达式的值为 0。如果&lt;code&gt;is_first为false&lt;/code&gt;（即这不是第一个字节），那么整个表达式的值为 128（&lt;code&gt;1000 0000&lt;/code&gt; in 二进制）。&lt;/li&gt;&lt;li&gt;这种结构在 MIDI 变长值的编码中很常见。MIDI 变长值的每个字节的最高位被用作”继续”位，指示是否有更多的字节跟随。如果最高位是 1，那么表示还有更多的字节；如果是 0，表示这是最后一个字节。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;在每次迭代中，它提取&lt;code&gt;tmp&lt;/code&gt;的最后 7 位并将其编码为一个字节，最高位根据是否是第一个字节来设置（如果是第一个字节，则为 0，否则为 1）。&lt;/li&gt;&lt;li&gt;然后，整数右移 7 位，以处理下一个字节。&lt;/li&gt;&lt;li&gt;请注意，这种编码方式实际上是从低字节到高字节的反向方式，所以接下来需要翻转这些字节。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;翻转字节&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;使用&lt;code&gt;mem.reverse&lt;/code&gt;翻转在固定缓冲区流中编码的字节。这是因为我们是以反序编码它们的，现在我们要将它们放在正确的顺序。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;写入结果&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;使用提供的&lt;code&gt;writer&lt;/code&gt;将翻转后的字节写入到目标位置。&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;filezig&quot;&gt;file.zig&lt;/h2&gt;&lt;p&gt;主要目的是为了表示和处理 MIDI 文件的不同部分，以及提供了一个迭代器来遍历 MIDI 轨道的事件。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;../midi.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;./decode.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Header&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;tracks&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Chunk&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file_header&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;MThd&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;track_header&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;MTrk&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MetaEvent&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind_byte&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u28&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MetaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind_byte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x00&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SequenceNumber&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x01&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x02&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;CopyrightNotice&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x03&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TrackName&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x04&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InstrumentName&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x05&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Luric&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x06&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Marker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x20&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiChannelPrefix&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x2F&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;EndOfTrack&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x51&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SetTempo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x54&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SmpteOffset&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x58&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TimeSignature&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x59&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;KeySignature&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;number&quot;&gt;0x7F&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SequencerSpecificMetaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;keyword_conditional&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Undefined&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SequenceNumber&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TextEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;CopyrightNotice&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TrackName&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;InstrumentName&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Luric&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Marker&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;CuePoint&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiChannelPrefix&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;EndOfTrack&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SetTempo&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SmpteOffset&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TimeSignature&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;KeySignature&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;SequencerSpecificMetaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TrackEvent&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;delta_time&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u28&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Kind&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;union&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;MidiEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;MetaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MetaEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;division&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u16&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;header_data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FileChunk&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FileChunk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;FileChunk&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;deinit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Allocator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;
            &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;chunks&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;allocator&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;header_data&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TrackIterator&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;FixedBufferStream&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TrackEvent&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TrackIterator&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;fixedBufferStream&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Result&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;TrackIterator&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Result&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;inStream&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;trackEvent&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;last_event&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword_exception&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;last_event&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_conditional&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MetaEvent&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;meta_event&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;meta_event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;MidiEvent&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi_event&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;keyword_conditional&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;midi_event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;ExclusiveStart&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;keyword_repeat&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword_exception&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0xF7&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
                    &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;keyword_repeat&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;constant label type variable variable_builtin&quot;&gt;blk&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword_return&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Header 结构&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;表示 MIDI 文件的头部。&lt;/li&gt;&lt;li&gt;包含一个块、格式、轨道数以及除法。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Chunk 结构&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;表示 MIDI 文件中的块，每个块有一个种类和长度。&lt;/li&gt;&lt;li&gt;定义了文件头和轨道头的常量。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;MetaEvent 结构&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;表示 MIDI 的元事件。&lt;/li&gt;&lt;li&gt;它有一个种类字节和长度。&lt;/li&gt;&lt;li&gt;有一个函数，根据种类字节返回事件的种类。&lt;/li&gt;&lt;li&gt;定义了所有可能的元事件种类。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;TrackEvent 结构&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;表示 MIDI 轨道中的事件。&lt;/li&gt;&lt;li&gt;它有一个 delta 时间和种类。&lt;/li&gt;&lt;li&gt;事件种类可以是 MIDI 事件或元事件。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;File 结构&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;表示整个 MIDI 文件。&lt;/li&gt;&lt;li&gt;它有格式、除法、头部数据和一系列块。&lt;/li&gt;&lt;li&gt;定义了一个子结构 FileChunk，用于表示文件块的种类和字节数据。&lt;/li&gt;&lt;li&gt;提供了一个清除方法来释放文件的资源。&lt;/li&gt;&lt;/ul&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;TrackIterator 结构&lt;/strong&gt;:&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;li&gt;是一个迭代器，用于遍历 MIDI 轨道的事件。&lt;/li&gt;&lt;li&gt;它使用一个 FixedBufferStream 来读取事件。&lt;/li&gt;&lt;li&gt;定义了一个 Result 结构来返回事件和关联的数据。&lt;/li&gt;&lt;li&gt;提供了一个&lt;code&gt;next&lt;/code&gt;方法来读取下一个事件。&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;build-zig&quot;&gt;Build.zig&lt;/h2&gt;&lt;p&gt;buid.zig 是一个 Zig 构建脚本（build.zig），用于配置和驱动 Zig 的构建过程。&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;builtin&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;builtin&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;std&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@import&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;std&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Builder&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Mode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;builtin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Mode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword_modifier&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword_function&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin variable_parameter variable type&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_all_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run all tests in all modes.&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;builtin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Mode&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;test_mode&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;builtin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Mode&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;mode_str&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@tagName&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_mode&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tests&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addTest&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;midi.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tests&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;setBuildMode&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_mode&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tests&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;setNamePrefix&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mode_str&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;test-&amp;quot;&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mode_str&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run all tests in &amp;quot;&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;mode_str&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;tests&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_all_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;examples&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Build examples&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;string&quot;&gt;&amp;quot;midi_file_to_text_stream&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example_name&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addExecutable&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example_name&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;example/&amp;quot;&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example_name&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;addPackagePath&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;midi&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;midi.zig&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;all&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Build everything and runs all tests&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_all_step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example_step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;default_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个 build 比较复杂，我们逐行来解析：&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_all_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Run all tests in all modes.&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;&lt;li&gt;使用 b.step() 方法定义了一个名为 test 的步骤。描述是”在所有模式下运行所有测试”。&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword_modifier&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;keyword_repeat&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@typeInfo&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;builtin&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Mode&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;punctuation_bracket operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;&lt;li&gt;Zig 有几种构建模式，例如 Debug、ReleaseSafe 等，上面则是为每种构建模式生成测试。&lt;ul&gt;&lt;li&gt;这里，@typeInfo() 函数获取了一个类型的元信息。std.builtin.Mode 是 Zig 中定义的构建模式的枚举。Enum.fields 获取了这个枚举的所有字段。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;examples&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Build examples&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;&lt;li&gt;配置示例构建，为所有示例创建的构建步骤。&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_step&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;all&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;Build everything and runs all tests&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;test_all_step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
all_step&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;example_step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

b&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;default_step&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;dependOn&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;all_step&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;&lt;li&gt;all_step 是一个汇总步骤，它依赖于之前定义的所有其他步骤。最后，b.default_step.dependOn(all_step);确保当你仅仅执行 zig build（没有指定步骤）时，all_step 会被执行。&lt;/li&gt;&lt;/ul&gt;</description>
        <link>https://ziglang.cc/post/2023-09-21-zig-midi/</link>
        <pubDate>Thu, 21 Sep 2023 15:15:02 +0000</pubDate>
        <guid>https://ziglang.cc/post/2023-09-21-zig-midi/</guid>
      </item>
    
      <item>
        <title>Bog GC Design</title>
        <description>&lt;h2 id=&quot;bog-gc-design&quot;&gt;Bog GC Design&lt;/h2&gt;&lt;p&gt;Bog is a small scripting language developed using Zig. Its GC design is inspired by a paper titled &lt;a href=&quot;https://www.pllab.riec.tohoku.ac.jp/papers/icfp2011UenoOhoriOtomoAuthorVersion.pdf&quot; target=&quot;_blank&quot;&gt;An efficient of Non-Moving GC for Function languages&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;Introduction&lt;ul&gt;&lt;li&gt;Design of the Heap&lt;/li&gt;&lt;li&gt;Types of GC&lt;/li&gt;&lt;li&gt;Design of Bitmap&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Implementation&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;&lt;p&gt;GC stands for garbage collection, which is primarily a memory management strategy for the &lt;code&gt;heap&lt;/code&gt; region. Memory allocations in the heap are done in exponentially increasing sizes, with a special sub-heap dedicated solely to very large objects. One advantage of this approach might be its efficiency in handling memory requests of various sizes.&lt;/p&gt;&lt;p&gt;Represented as a formula:&lt;/p&gt;&lt;p&gt;$$ Heap = (M, S, (H_3, H_4, …, H_{12})) $$&lt;/p&gt;&lt;p&gt;Where:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;M: is a special region dedicated to storing large objects.&lt;/li&gt;&lt;li&gt;S: represents the free space.&lt;/li&gt;&lt;li&gt;H: is the sub-heap used for storing smaller objects. $H_i$ represents the sub-heap of size $2^i$, where each addition is twice the size of the previous.&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;mermaid&quot;&gt;
graph TD
  A[Heap]
  B[M]
  C[S]
  D[H:Sub Heap]

  A --&gt; B
  A --&gt; C
  A --&gt; D
  D --&gt; H3
  D --&gt; H4
  D --&gt; H5
  D --&gt; Hi
&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;+------------+&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;Container&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;Box&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;Box&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;Box&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;+------------+&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;memory-sub-heap-pool&quot;&gt;Memory Sub-Heap Pool&lt;/h3&gt;&lt;p&gt;We’ve designed a memory resource pool. This pool consists of numerous allocation segments of fixed size. It means that, regardless of how much space a sub-heap requests, it will request it in units of these fixed-size “segments”. For instance, if the allocation segments in the pool are of size 1MB, then a sub-heap might request space in sizes of 1MB, 2MB, 3MB, etc., rather than requesting non-integer multiples like 1.5MB or 2.5MB.&lt;/p&gt;&lt;p&gt;The dynamic allocation and reclaiming of space by the sub-heaps from a resource pool made up of fixed-size segments provide greater flexibility and may enhance the efficiency of memory utilization.&lt;/p&gt;&lt;h3 id=&quot;types-of-gc&quot;&gt;Types of GC&lt;/h3&gt;&lt;p&gt;There are many common types of GC.&lt;/p&gt;&lt;p&gt;In terms of &lt;strong&gt;bitmap recorded data&lt;/strong&gt;, there exists “Generational Garbage Collection”. In Generational Garbage Collection, “generations” or “ages” do not refer to the bitmap. They actually denote portions of the memory used to store objects. Based on the lifespan of objects, GC categorizes them into different generations. The fundamental idea behind this strategy is that newly created objects will become garbage sooner, whereas older objects might live longer.&lt;/p&gt;&lt;p&gt;Generally, in Generational GC, there are two primary generations:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Young Generation&lt;/strong&gt;: Newly created objects are initially placed here. The Young Generation space is usually smaller and is garbage collected frequently.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Old or Tenured Generation&lt;/strong&gt;: After objects have lived in the Young Generation for a sufficient amount of time and have survived several garbage collections, they are moved to the Old Generation. The Old Generation space is typically larger than the Young Generation, and garbage collection occurs less frequently since objects in the Old Generation are expected to have a longer lifespan.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Bitmaps serve as a tool here, used to track and manage which objects in each generation are active (i.e., still in use) and which are garbage. When the algorithm extends to Generational GC, multiple bitmaps can be maintained for different generations within the same heap space. In this way, active and inactive objects of each generation can be tracked individually.&lt;/p&gt;&lt;p&gt;“Maintain one bitmap for the Young Generation and another for the Old Generation.” This allows us to consider each generation separately during garbage collection, optimizing the efficiency and performance of the collection process.&lt;/p&gt;&lt;p&gt;In terms of &lt;strong&gt;moving existing data&lt;/strong&gt;, there are “Moving GC” and “Non-Moving GC”. Moving GC relocates living objects to new memory addresses and compresses memory, while Non-Moving GC doesn’t move living objects, allowing other languages to seamlessly call data in memory.&lt;/p&gt;&lt;p&gt;Within this Moving GC category, there are “Generational Copying Collectors” and “Cheney’s Copying Collector”.&lt;/p&gt;&lt;p&gt;Generational Copying Collector: It is a common method of garbage collection, especially in functional programming languages. It assumes that newly created objects will soon become unreachable (i.e., “die”), whereas older objects are more likely to persist. Thus, memory is divided into two or more “generations”. New objects are created in the “Young Generation”, and when they live long enough, they are moved to the “Old Generation”.&lt;/p&gt;&lt;p&gt;Cheney’s Copying Collector: This is a garbage collector used for semi-space. It works by dividing the available memory in half and only allocating objects in one half. When this half is exhausted, the collector performs garbage collection by copying active objects to the other half. The original half is then completely emptied, becoming the new available space. Cheney’s collector is particularly suited for handling data with short lifespans because it quickly copies only the active data while ignoring the dead data. This makes it highly efficient for its “minor collections” (collections that only reclaim Young Generation data) when dealing with programs that handle a large amount of short-lifetime data, such as functional programs. &lt;strong&gt;The advantage of this method is that it can efficiently handle memory fragmentation since memory becomes continuously occupied by copying active objects to new locations.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Characteristics:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Any precise copy gc requires the runtime system to locate and update all pointers of every heap-allocated data.&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;In traditional garbage collection strategies (Moving GC), compaction is a commonly used technique, moving active objects into a contiguous region of memory, thereby freeing up unused memory. In other words, it consolidates memory fragmentation.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In Non-Moving GC, there’s “Mark-Sweep”.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The absence of compaction and object movement is very important&lt;/strong&gt;, as the value of a pointer (i.e., the memory address of an object) remains fixed and there’s no time spent updating moved addresses. This makes Non-Moving GC highly suitable for languages that need to interact with other languages, as they can access objects in memory without the need for extra work. Moreover, the feature of not moving objects is beneficial for supporting multiple native threads. In a multi-threaded environment, if the location of an object in memory keeps shifting, coordination and synchronization between threads become more complicated. Therefore, avoiding object movement simplifies multithreaded programming.&lt;/p&gt;&lt;p&gt;The benefits are as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lock Simplification&lt;/strong&gt;: In a multi-threaded environment, if an object needs to be moved (e.g., during the compaction phase of garbage collection), we need to ensure other threads cannot access this object while it’s moving. This might require complex locking strategies and synchronization mechanisms. However, if objects never move, this synchronization need is reduced, making locking strategies simpler.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pointer Stability&lt;/strong&gt;: In multi-threaded programs, threads might share pointers or references to objects. If an object moves in memory, all threads sharing that object would need to update their pointers or references. This not only adds synchronization complexity but might also introduce errors, like dangling pointers. If objects don’t move, these pointers remain consistently valid.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Predictability and Performance&lt;/strong&gt;: Not having to move objects means memory access patterns are more stable and predictable. In multi-threaded programs, predictability is a valuable trait as it can reduce contention between threads, improving overall program performance.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduced Pause Times&lt;/strong&gt;: Object movement in garbage collection can lead to noticeable pauses in an application because all threads must be paused to move objects safely. In a multi-threaded environment, this pause might be more pronounced as more threads might actively use objects. Not moving objects reduces such pauses.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interoperability with Other Languages or Systems&lt;/strong&gt;: If your multi-threaded application interoperates with other languages (like C or C++) or systems, having objects in stable locations becomes even more crucial since external code might rely on the fact that objects aren’t moving.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;However, Non-Moving GC has its disadvantages:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Memory Fragmentation&lt;/strong&gt;: Since objects don’t move, spaces in memory might become non-contiguous. This could lead to memory fragmentation, decreasing memory usage efficiency.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Memory Allocation&lt;/strong&gt;: Due to fragmentation, memory allocation can become more complicated. For instance, if there isn’t enough contiguous space to meet an allocation request, the allocator might need to do more work to find available space. This might decrease allocation performance.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Memory Usage&lt;/strong&gt;: Due to fragmentation, memory usage can become less efficient. For instance, if there’s a large object without enough contiguous space to store it, it might get split into multiple fragments which could be assigned to different contiguous spaces, potentially decreasing memory utilization.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Memory Overhead&lt;/strong&gt;: Due to fragmentation, memory overhead can become less efficient. For instance, if there’s a large object without enough contiguous space to store it, it might get split into multiple fragments which could be assigned to different contiguous spaces, potentially decreasing memory utilization.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;……&lt;/p&gt;&lt;p&gt;To address these problems requires many complicated steps, which won’t be elaborated on here. We’ll focus on Bog’s GC for the explanation.&lt;/p&gt;&lt;h3 id=&quot;meta-bitmap&quot;&gt;Meta Bitmap&lt;/h3&gt;&lt;p&gt;“Meta Bitmap” or “meta-level bitmaps”. This is a higher-level bitmap that summarizes the contents of the original bitmap. This hierarchical structure is similar to the inode mapping in file systems or the use of multi-level page tables in computer memory management.&lt;/p&gt;&lt;p&gt;For instance, consider a simple bitmap: &lt;code&gt;1100 1100&lt;/code&gt;. A meta-level bitmap might represent how many free blocks are in every 4 bits. In this scenario, the meta-level bitmap could be &lt;code&gt;1021&lt;/code&gt; (indicating there’s 1 free block in the first 4 bits, 2 free blocks in the second 4 bits, and so on).&lt;/p&gt;&lt;p&gt;The system doesn’t just blindly start searching from the beginning of the bitmap for a free bit; it remembers the last-found position. This way, the next search can begin from this position, speeding up the search process further. This means that the time needed to find the next free bit remains approximately the same, regardless of memory size, which is a very efficient performance characteristic.&lt;/p&gt;&lt;p&gt;What about the worst-case scenario?&lt;/p&gt;&lt;p&gt;Let’s design for a 32-bit architecture. A 32-bit architecture means that the computer’s instruction set and data path are designed to handle data units 32 bits wide. Therefore, when operating on 32-bit data units (like an integer or part of a bitmap), such an architecture can typically process all 32 bits at once. This results in logarithmic operations based on 32, because for larger data sections (like a bitmap), operations might need to proceed in blocks/chunks of 32 bits. &lt;strong&gt;The search time is logarithmically related to the size of segmentSize&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;For example, if a bitmap is 320 bits long, then on a 32-bit architecture, the worst-case scenario might require checking 10 blocks of 32 bits to find a free bit. This can be represented by log32(320), which results in 10.&lt;/p&gt;&lt;h3 id=&quot;bitmap&quot;&gt;Bitmap&lt;/h3&gt;&lt;p&gt;Since Bog’s GC is essentially still based on “Mark-Sweep”, using bitmaps to record data is indispensable. In Bog, we adopted the method of “bitmap records data” for GC. And to improve efficiency, we introduced the concept of meta-bitmaps, where every 4 elements correspond to a meta-bitmap, recording the occupancy status of multiple spaces, and increasing the depth based on the object age in the heap.&lt;/p&gt;&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;/h3&gt;&lt;p&gt;In reality, Bog’s design is a bit more complex. Here are sample in practical code:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Page&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max_size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1_048_576&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 2^20, 1MiB&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max_size&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;val_count&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@divFloor&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max_size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pad_size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max_size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val_count&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;&lt;li&gt;&lt;code&gt;max_size&lt;/code&gt;: Represents the maximum number of bytes a Page can store. We have defined a constant to represent the size of 1 MiB and ensure at compile time that the size of the Page type is exactly 1 MiB. Otherwise, a compile-time error will be triggered.&lt;/li&gt;&lt;li&gt;&lt;code&gt;val_count&lt;/code&gt;: Represents the number of Value objects a Page can store.&lt;/li&gt;&lt;li&gt;&lt;code&gt;pad_size&lt;/code&gt;: Represents the size of the unused space remaining in the Page after storing the maximum number of Value objects.&lt;/li&gt;&lt;/ol&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;white&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gray&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;black&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;ArrayListUnmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val_count&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;__padding&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pad_size&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;marked&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val_count&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;&lt;li&gt;An enumeration type named &lt;code&gt;State&lt;/code&gt; is defined, which has four possible values: empty, white, gray, and black.&lt;ul&gt;&lt;li&gt;In the context of Garbage Collection (GC), these states are typically related to the status of objects during the GC process. For instance, in generational garbage collection, an object might be marked as “white” (unvisited/pending), “gray” (visited but its references not yet processed), or “black” (processed).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;List&lt;/code&gt;: Stores pointers of the Page type.&lt;/li&gt;&lt;li&gt;&lt;code&gt;meta&lt;/code&gt;: Represents the state of each Value object within a Page. Here, we use an enum type to represent the state, and since there are only 4 states, they can be represented using 2 bits. Thus, we can use a u32 to represent the state of all Value objects within a Page. Each State potentially corresponds to the status of a Value object in the &lt;code&gt;values&lt;/code&gt; field.&lt;/li&gt;&lt;li&gt;A &lt;code&gt;__padding&lt;/code&gt; field, used to pad extra memory space. Its size is determined by the previously mentioned &lt;code&gt;pad_size&lt;/code&gt; and is an array of bytes (u8). This is commonly used to ensure memory alignment of data structures.&lt;/li&gt;&lt;li&gt;&lt;code&gt;free&lt;/code&gt;: Represents the number, index, or other information related to free or available spaces concerning memory management.&lt;/li&gt;&lt;li&gt;&lt;code&gt;marked&lt;/code&gt;: Represents the number, index, or other information about marked spaces, used during the garbage collection process to determine whether to continue checking values on this page.&lt;/li&gt;&lt;li&gt;&lt;code&gt;values&lt;/code&gt;: Represents the Value objects in a Page. It’s an array of Value objects, the size of which is determined by &lt;code&gt;val_count&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;</description>
        <link>https://ziglang.cc/post/2023-09-05-bog-gc-1-en/</link>
        <pubDate>Tue, 05 Sep 2023 08:40:50 +0000</pubDate>
        <guid>https://ziglang.cc/post/2023-09-05-bog-gc-1-en/</guid>
      </item>
    
      <item>
        <title>Bog GC 设计 -- 概念篇</title>
        <description>&lt;h2 id=&quot;bog-gc-design-concepts&quot;&gt;Bog GC Design – Concepts&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/Vexu/bog&quot; target=&quot;_blank&quot;&gt;Bog&lt;/a&gt; 是一款基于 Zig 开发的小型脚本语言。它的 GC 设计受到一篇论文&lt;a href=&quot;https://www.pllab.riec.tohoku.ac.jp/papers/icfp2011UenoOhoriOtomoAuthorVersion.pdf&quot; target=&quot;_blank&quot;&gt;An efficient of Non-Moving GC for Function languages&lt;/a&gt;的启发。&lt;/p&gt;&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;&lt;p&gt;GC 是一种垃圾回收的机制，主要是针对&lt;code&gt;heap&lt;/code&gt;区域的内存管理策略。在堆中的内存分配是按照指数级增长的大小进行的，此外还有一个专门用于非常大对象的特殊子堆。这种方法的一个优点可能是它可以高效地处理各种大小的内存请求。&lt;/p&gt;&lt;p&gt;以公式来进行表示：&lt;/p&gt;&lt;p&gt;$$ Heap = (M, S, (H_3, H_4, …, H_{12})) $$&lt;/p&gt;&lt;p&gt;其中：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;M 是特殊的区域，用于存储大对象&lt;/li&gt;&lt;li&gt;S 是空闲区域&lt;/li&gt;&lt;li&gt;H 是子堆，用于存储小对象，$H_i$表示大小为$2^i$的子堆，每次新增都为之前的两倍&lt;/li&gt;&lt;/ol&gt;&lt;pre class=&quot;mermaid&quot;&gt;
graph TD
  A[Heap]
  B[M]
  C[S]
  D[H:Sub Heap]

  A --&gt; B
  A --&gt; C
  A --&gt; D
  D --&gt; H3
  D --&gt; H4
  D --&gt; H5
  D --&gt; Hi
&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;constant function&quot;&gt;+------------+&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;Container&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;Box&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;Box&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;constant function&quot;&gt;Box&lt;/span&gt; &lt;span class=&quot;constant&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;constant function&quot;&gt;+------+&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;constant function&quot;&gt;+------------+&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;memory-sub-heap-pool&quot;&gt;Memory Sub-Heap Pool&lt;/h3&gt;&lt;p&gt;我们设计一个内存的资源池。这个池由许多固定大小的分配段组成。这意味着，无论子堆请求多少空间，它都会以这些固定大小的”段”为单位来请求。例如，如果池中的分配段大小为 1MB，那么一个子堆可能会请求 1MB、2MB、3MB 等大小的空间，而不是请求 1.5MB 或 2.5MB 这样的非整数倍的大小。&lt;/p&gt;&lt;p&gt;而子堆从一个由固定大小的段组成的资源池中动态分配和回收空间，这种策略可以提供更高的灵活性，并可能提高内存使用的效率。&lt;/p&gt;&lt;h3 id=&quot;types-of-gc&quot;&gt;Types of GC&lt;/h3&gt;&lt;p&gt;常见的 GC 有很多类型。&lt;/p&gt;&lt;p&gt;以&lt;strong&gt;位图记录数据&lt;/strong&gt;来说，有”代际垃圾收集 GC”。在代际垃圾收集（Generational Garbage Collection）中，“代”或”世代”并不是指位图。它们实际上是指内存中的一部分，用于存储对象。基于对象的生存周期，GC 把它们分为不同的代。这种策略背后的基本思想是，新创建的对象很快就会变为垃圾，而旧对象则可能存活得更久。&lt;/p&gt;&lt;p&gt;一般来说，在代际 GC 中，有两个主要的代：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;新生代（Young Generation）&lt;/strong&gt;：新创建的对象首先被放置在这里。新生代空间通常较小，并且经常进行垃圾收集。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;老年代（Old or Tenured Generation）&lt;/strong&gt;：当对象在新生代中存活了足够长的时间并经历了多次垃圾收集后，它们会被移动到老年代。老年代空间通常比新生代大，并且垃圾收集的频率较低，因为预期老年代中的对象会有更长的生命周期。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;位图在这里是一个工具，用于跟踪和管理每一代中哪些对象是活跃的（即仍在使用中）和哪些是垃圾。当算法扩展为代际 GC 时，可以为同一个堆空间的不同代维护多个位图。这样，每个代的活动和非活动对象都可以被单独地跟踪。&lt;/p&gt;&lt;p&gt;“为新生代维护一个位图，为老年代维护另一个位图”。这使得在进行垃圾收集时，我们可以单独地考虑每一个代，从而优化垃圾收集的效率和性能。&lt;/p&gt;&lt;p&gt;以是否&lt;strong&gt;移动旧有的数据&lt;/strong&gt;来说，有”移动 GC”和”非移动 GC”。移动 GC 会将存活的对象移动到新的内存地址、压缩内存，而非移动 GC 则不会移动存活的对象，可以无缝由其他语言来调用内存里的数据。&lt;/p&gt;&lt;p&gt;在这种移动 GC 中，有”分代复制收集器”和”Cheney 复制收集器”。&lt;/p&gt;&lt;p&gt;分代复制收集器 (Generational Copying Collector): 是垃圾收集的一种常见方法，特别是在函数式编程语言中。它假设新创建的对象很快就会变得不可达（即”死亡”），而老的对象则更可能持续存在。因此，内存被分成两个或更多的”代”，新对象在”新生代”中创建，当它们存活足够长的时间时，它们会被移到”老生代”。&lt;/p&gt;&lt;p&gt;Cheney 的拷贝收集器：是一种用于半区（semi-space）的拷贝垃圾收集器。它的工作原理是将可用内存分为两半，并且只在其中一半中分配对象。当这一半用完时，收集器通过拷贝活跃对象到另一半空间来进行垃圾收集。然后，原先的那一半空间就完全清空，成为新的可用空间。Cheney 的收集器特别适用于处理短生命周期的数据，因为它可以快速地只拷贝活跃的数据，而忽略死亡的数据。这使得它在处理大量短生命周期数据的程序（例如函数式程序）时，对于其”次要收集”（minor collection，即仅仅回收新生代数据的收集）非常高效。&lt;strong&gt;这种方法的优势在于它可以有效地处理内存碎片，因为通过复制活动对象到新位置，内存会被连续地占用。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;特点：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;任何精确的 copy gc 都需要 runtime 系统定位和更新每个堆分配数据的所有指针&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;在传统的垃圾收集策略（移动 GC）中，压缩是一种常用的技术，它会将活跃的对象移到内存的一个连续区域中，从而释放出未使用的内存。换言之，就是整理内存碎片。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;在非移动 GC 中，有”标记 - 清除”。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;不需要进行压缩和对象移动这一特性是非常重要&lt;/strong&gt;，指针的值（即对象的内存地址）是固定的，也不需要花时间更新移动的地址。这使得非移动 GC 非常适合于需要与其他语言进行交互的语言，因为它们可以在不需要额外的工作的情况下访问内存中的对象。而且不需要移动对象的这一特性对于支持多原生线程也是有益的。在多线程环境中，如果对象在内存中的位置不断移动，那么线程之间的协调和同步将变得更加复杂。因此，避免对象移动可以简化多线程编程。&lt;/p&gt;&lt;p&gt;有益的原因如下：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;锁的简化&lt;/strong&gt;: 在一个多线程环境中，如果对象需要移动（例如，在垃圾收集的压缩阶段），那么我们需要确保其他线程在对象移动时不能访问这个对象。这可能需要使用复杂的锁策略和同步机制。但是，如果对象永远不移动，我们就可以减少这种同步的需求，使得锁策略更简单。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;指针的稳定性&lt;/strong&gt;: 在多线程程序中，线程之间可能会共享指向对象的指针或引用。如果对象在内存中移动了，那么所有共享该对象的线程都需要更新其指针或引用。这不仅会增加同步的复杂性，而且可能会引入错误，如野指针。如果对象不移动，这些指针就会始终有效。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;预测性和性能&lt;/strong&gt;: 不需要移动对象意味着内存访问模式更加稳定和可预测。在多线程程序中，预测性是一个宝贵的特性，因为它可以减少线程之间的争用，从而提高程序的整体性能。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;减少暂停时间&lt;/strong&gt;: 垃圾收集中的对象移动可能导致应用程序的明显暂停，因为必须暂停所有线程来安全地进行移动。在多线程环境中，这种暂停可能更加明显，因为有更多的线程可能正在活跃地使用对象。不移动对象可以减少这种暂停。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;与其他语言或系统的互操作&lt;/strong&gt;: 如果您的多线程应用程序与其他语言（如 C 或 C++）或系统进行互操作，那么对象的稳定位置将更加重要，因为外部代码可能依赖于对象不移动的事实。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;但同样的，非移动 GC 也有缺点：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;内存碎片&lt;/strong&gt;: 由于对象不会移动，因此内存中的空间可能会变得不连续。这可能会导致内存碎片，从而降低内存使用效率。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;内存分配&lt;/strong&gt;: 由于内存碎片，内存分配可能会变得更加复杂。例如，如果没有足够的连续空间来满足分配请求，那么分配器可能需要进行更多的工作来查找可用的空间。这可能会导致分配的性能下降。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;内存使用&lt;/strong&gt;: 由于内存碎片，内存使用可能会变得更加低效。例如，如果有一个大对象，但是没有足够的连续空间来存储它，那么它可能会被分成多个碎片，这些碎片可能会被分配给不同的连续空间。这可能会导致内存使用率降低。&lt;/li&gt;&lt;li&gt;&lt;strong&gt;内存占用&lt;/strong&gt;: 由于内存碎片，内存占用可能会变得更加低效。例如，如果有一个大对象，但是没有足够的连续空间来存储它，那么它可能会被分成多个碎片，这些碎片可能会被分配给不同的连续空间。这可能会导致内存使用率降低。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;为了解决这些问题需要很多复杂的步骤，在此不多赘述。单以 Bog 的 GC 来讲解。&lt;/p&gt;&lt;h3 id=&quot;meta-bitmap&quot;&gt;Meta Bitmap&lt;/h3&gt;&lt;p&gt;“元级位图”或”meta-level bitmaps”。这是一个更高级别的位图，用于汇总原始位图的内容。这种层次化的结构类似于文件系统中的 inode 映射或多级页表在计算机内存管理中的使用。&lt;/p&gt;&lt;p&gt;例如，考虑一个简单的位图：&lt;code&gt;1100 1100&lt;/code&gt;。一个元级位图可能表示每 4 位中有多少个空闲块。在这种情况下，元级位图可能是 &lt;code&gt;1021&lt;/code&gt;（表示第一个 4 位中有 1 个空闲块，第二个 4 位中有 2 个空闲块，以此类推）。&lt;/p&gt;&lt;p&gt;系统不仅仅是盲目地从位图的开始处查找空闲位，而是记住上一次查找到的位置。这样，下次查找可以从这个位置开始，进一步加速查找过程。这意味着无论内存大小如何，找到下一个空闲位所需的时间都大致相同，这是一个非常高效的性能特性。&lt;/p&gt;&lt;p&gt;如果是最坏的情况呢？&lt;/p&gt;&lt;p&gt;以 32 位架构来设计。32 位架构意味着计算机的指令集和数据路径设计为处理 32 位宽的数据单元。因此，当操作 32 位数据单元（例如一个整数或位图的一部分）时，这样的架构通常可以一次性处理所有 32 位。这导致以 32 为底的对数操作，因为对于较大的数据段（如一个位图），操作可能需要按 32 位的块/段进行。&lt;strong&gt;查找时间与 segmentSize 的大小成对数关系&lt;/strong&gt;。&lt;/p&gt;&lt;p&gt;例如，如果一个位图有 320 位，那么在 32 位架构上，最坏的情况可能需要检查 10 个 32 位块才能找到一个空闲位。这可以通过 $\log_{32}(320)$来表示，结果是 10。&lt;/p&gt;&lt;h3 id=&quot;bitmap&quot;&gt;Bitmap&lt;/h3&gt;&lt;p&gt;由于 Bog 的 GC 本质上还是采用了”标记 - 清除”，所以利用位图来记录数据是必不可少的。在 Bog 中，我们采用了”位图记录数据”的方式来进行 GC。而为了提高效率，我们增加了元位图的概念，即每 4 个元素对应一个元位图，用于记录多空间的占用状态，并且根据 heap 的对象时间增加深度。&lt;/p&gt;&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;/h3&gt;&lt;p&gt;实际上，在 Bog 的设计中，要更加复杂一些。我们增加了&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Page&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max_size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1_048_576&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword_modifier&quot;&gt;comptime&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment_documentation comment spell&quot;&gt;// 2^20, 1MiB&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin function_call variable type&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max_size&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;module constant variable_builtin type variable&quot;&gt;val_count&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;function_builtin keyword_import&quot;&gt;@divFloor&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max_size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pad_size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;max_size&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;function_builtin&quot;&gt;@sizeOf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val_count&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;variable_builtin&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;&lt;li&gt;&lt;code&gt;max_size&lt;/code&gt;: 表示一个 Page 能够存储的最大字节数。我们定义了一个常量来表示 1 MiB 的大小，并在编译时确保 Page 类型的大小恰好为 1 MiB。否则将会触发编译时错误。&lt;/li&gt;&lt;li&gt;&lt;code&gt;val_count&lt;/code&gt;: 表示一个 Page 能够存储的 Value 对象的数量&lt;/li&gt;&lt;li&gt;&lt;code&gt;pad_size&lt;/code&gt;: 表示在存储了最大数量的 Value 对象后，Page 剩余的未使用的空间大小&lt;/li&gt;&lt;/ol&gt;&lt;pre&gt;&lt;code class=&quot;zig&quot;&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;keyword_type&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;white&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;gray&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;black&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;constant variable_builtin type variable&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;type constant variable_builtin function_call variable_member variable&quot;&gt;ArrayListUnmanaged&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val_count&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;__padding&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;pad_size&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;marked&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;constant variable_builtin type variable_member variable&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;val_count&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;constant variable_builtin type variable&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;&lt;li&gt;定义了一个名为 State 的枚举类型，它有四个可能的值：empty、white、gray 和 black。&lt;ul&gt;&lt;li&gt;在垃圾收集（GC）的上下文中，这些状态通常与对象在 GC 过程中的状态有关。例如，在分代垃圾收集中，对象可能会被标记为 “white”（未访问/待处理），“gray”（已访问但其引用尚未处理）或 “black”（已处理）。&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;List&lt;/code&gt;: 存储 Page 类型的指针&lt;/li&gt;&lt;li&gt;&lt;code&gt;meta&lt;/code&gt;: 表示一个 Page 中每个 Value 对象的状态。这里我们使用了一个枚举类型来表示状态，因为状态只有 4 种，所以可以用 2 位来表示。因此，我们可以使用一个 u32 来表示一个 Page 中所有 Value 对象的状态。这样，我们就可以使用一个 u32 来表示一个 Page 中所有 Value 对象的状态。每一个 State 可能对应一个在 values 字段中的 Value 对象的状态。&lt;/li&gt;&lt;li&gt;&lt;code&gt;__padding&lt;/code&gt; 的字段，用于填充额外的内存空间。它的大小由之前提到的 pad_size 决定，且是一个字节（u8）数组。这通常用于确保数据结构的内存对齐。&lt;/li&gt;&lt;li&gt;&lt;code&gt;free&lt;/code&gt;: 表示空闲或可用的空间数量、索引或其他与内存管理相关的信息&lt;/li&gt;&lt;li&gt;&lt;code&gt;marked&lt;/code&gt;: 表示已标记的空间数量、索引或其他与内存管理相关的信息，在垃圾收集的过程中用于检测是否应继续在此页面中检查值&lt;/li&gt;&lt;li&gt;&lt;code&gt;values&lt;/code&gt;: 表示一个 Page 中的 Value 对象。它是一个 Value 对象的数组，其大小由 val_count 决定。&lt;/li&gt;&lt;/ol&gt;</description>
        <link>https://ziglang.cc/post/2023-09-05-bog-gc-1/</link>
        <pubDate>Tue, 05 Sep 2023 08:38:36 +0000</pubDate>
        <guid>https://ziglang.cc/post/2023-09-05-bog-gc-1/</guid>
      </item>
    
      <item>
        <title>欢迎 Zig 爱好者向本网站供稿</title>
        <description>&lt;p&gt;欢迎社区用户向 ZigCC 供稿（关于 Zig 的任何话题），方便与社区更多人分享。文章会发布在：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://ziglang.cc&quot; target=&quot;_blank&quot;&gt;ZigCC 网站&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/zigcc/.github/raw/main/zig_mp.png&quot; target=&quot;_blank&quot;&gt;ZigCC 公众号&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;contribute&quot;&gt;供稿方式&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;Fork 仓库 &lt;a href=&quot;https://github.com/zigcc/zigcc.github.io&quot; target=&quot;_blank&quot;&gt;https://github.com/zigcc/zigcc.github.io&lt;/a&gt;&lt;/li&gt;&lt;li&gt;在 &lt;code&gt;content/post&lt;/code&gt; 内添加自己的文章（smd 格式），文件命名为： &lt;code&gt;${YYYY}-${MM}-${DD}-${SLUG}.smd&lt;/code&gt;&lt;/li&gt;&lt;li&gt;文件开始需要包含一些描述信息，例如：&lt;/li&gt;&lt;/ol&gt;&lt;pre&gt;&lt;code class=&quot;ziggy&quot;&gt;&lt;span class=&quot;error&quot;&gt;---&lt;/span&gt;
.&lt;span class=&quot;keyword&quot;&gt;title&lt;/span&gt; = &lt;span class=&quot;string&quot;&gt;&amp;quot;文章标题&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
.&lt;span class=&quot;keyword&quot;&gt;date&lt;/span&gt; = @&lt;span class=&quot;function&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;2025-06-05T16:00:00+0800&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
.&lt;span class=&quot;keyword&quot;&gt;author&lt;/span&gt; = &lt;span class=&quot;string&quot;&gt;&amp;quot;刘家财&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
.&lt;span class=&quot;keyword&quot;&gt;layout&lt;/span&gt; = &lt;span class=&quot;string&quot;&gt;&amp;quot;post.shtml&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
.&lt;span class=&quot;keyword&quot;&gt;draft&lt;/span&gt; = &lt;span class=&quot;constant_builtin_boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
.&lt;span class=&quot;keyword&quot;&gt;custom&lt;/span&gt; = &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
  .&lt;span class=&quot;keyword&quot;&gt;math&lt;/span&gt; = &lt;span class=&quot;constant_builtin_boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_line&quot;&gt;// 如果你要用到数学公式，请 设置 math 为 true; 否则可以忽略&lt;/span&gt;
  .&lt;span class=&quot;keyword&quot;&gt;mermaid&lt;/span&gt; = &lt;span class=&quot;constant_builtin_boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;comment_line&quot;&gt;// 如果你要用到 mermaid 图表，请设置 mermaid 为 true; 否则可以忽略&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;error&quot;&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;local-preview&quot;&gt;本地预览&lt;/h2&gt;&lt;p&gt;在写完文章后，可以使用 &lt;a href=&quot;https://zine-ssg.io/&quot; target=&quot;_blank&quot;&gt;zine&lt;/a&gt; 进行本地预览，只需在项目根目录执行 &lt;code&gt;zine&lt;/code&gt;，这会启动一个 HTTP 服务，默认的访问地址是：&lt;a href=&quot;http://localhost:1990/&quot; target=&quot;_blank&quot;&gt;http://localhost:1990/&lt;/a&gt;&lt;/p&gt;</description>
        <link>https://ziglang.cc/post/2023-09-05-hello-world/</link>
        <pubDate>Tue, 05 Sep 2023 08:13:13 +0000</pubDate>
        <guid>https://ziglang.cc/post/2023-09-05-hello-world/</guid>
      </item>
    
  </channel>
</rss>
