编程语言研究书库

你的第一个 Zig 程序 — Hello World 解剖课

你的第一个 Zig 程序 — Hello World 解剖课

这一章把「Hello, World」当成解剖课标本。 别的书让你抄一遍就跑, 这本书把五行的程序拆成零件,再让你不用 zig run 这个快捷键、 亲手把「编译、运行」两个步骤各做一遍。读完你会:看懂一个 Zig 程序的每个 token, 知道 zig run 背后发生了什么,掌握 const / var / undefined 三条变量纪律, 并认识 Debug 模式下的 0xaa 陷阱标志——全书第一个「Zig 替你兜底」的具体机制。

1. 这一章讲什么

章节链条位置:第 1 章给了「为什么」,第 2 章给了「台面」,这一章给你「第一个程序」。 它是全书第一条真正动手的主线例子,后面第 4 章(控制流)直接从这章的变量讲起。

2. 顶层全景:一条从源码到屏幕的流水线

  main.zig(源文件,纯文本)
      │  ① zig build-exe:编译成机器码 → main(可执行文件) + main.o(目标文件)
      │  ② ./main:操作系统加载、运行 → 屏幕输出
      │
      ├─ 快捷方式:zig run = ①+② 一口气做完
      │
      └─ 项目版:zig init 生成四个文件 → zig build → zig-out/bin/ 里的成品

  图说:左半边是「一句话程序」的两步法;右半边是「一个项目」的构建系统入口。
       本章一半讲左半边,一半讲右半边。

本章主线例子:五行打印程序 std.debug.print("Hello Zig! \n", .{});, 从源码到屏幕逐步走,每一步旁边是具体产生的文件和字节;变量部分再拿 var x: i32 = undefined 走第二遍,看 0xaa 如何现形。

3. 核心原理一:五行程序的逐 token 解剖

程序本体(照原书):

  const std = @import("std");

  pub fn main() void {
      std.debug.print("Hello Zig! \n", .{});
  }

3.1 main:每个程序的入口

pub fn main() void { ... } 拆开是四件东西1:

部件意思
pubpublic,公开的——允许被项目外访问(main 必须公开,操作系统要进来调它)
fnfunction,函数:一段有名、可被调用的代码
main这个名字是约定的入口:程序启动时操作系统第一个调用的函数
() 和 void不接收参数、不返回任何东西(void = 空)

书里特意说:这已经是一个合法的 Zig 程序。zig run main.zig 跑它,没有任何输出、 也没有任何错误——空 main 就是空程序2。

3.2 @import:把标准库整个拿进来

const std = @import("std"); 一行做两件事:调用编译器内建函数 @import 加载标准库; 把加载结果绑到常量 std 上3。

解释词:内建函数(built-in function)。 Zig 里 @ 开头的是编译器直接提供的函数, 不是标准库里的普通函数——@import 就是内建函数,名字前的 @ 是它的徽记4。

@import 的正式签名(照原书引用官方文档):@import(comptime path: []const u8) type。 翻译成人话:它吃一个编译期已知的文件路径字符串,找到对应的 Zig 文件, 把这个文件的内容当作一个结构体(struct)返回——「Zig 源文件隐式就是结构体, 名字就是文件名去掉扩展名」5。所以 std 本质上是一个巨大的命名空间(命名空间 = 一组名字的家,用点号分层访问), std.debug、std.mem 这些点号路径都是它里面的成员。

3.3 全书第一个「jump scare」:Zig 没有字符串

原书的原文提醒:「系好安全带——Zig 里没有字符串。」6

不是夸张,是字面意思:语言里没有 string 这个类型。你写在引号里的 "Hello Zig! \n", 真实身份是一串字节(byte:8 位二进制,值域 0–255 的最小存储单位)的切片(slice)。 切片是什么,原书的注释版解释照收:

切片是对一串值的引用——这里是字节。把它想成「一个指向数组的指针,但带着已知的长度」。7

指针(第 9 章细讲)这里先按「地址」理解:切片 = 起始地址 + 长度,两样打包。 轻量、高效、没有多余开销,这正是系统级语言要的。

这件事为什么重要(我们的解读,书里没展开):字符串是一串带解释规则的字节 (UTF-8 编码、长度可变),而字节切片只是一块裸内存的视图。 Zig 把「文本」降格成「字节」,等于把编码、长度、合法性这些决定权全部交给你—— 第 1 章「透明」处方在数据类型上的第一次落地。代价是:文本处理比别的语言啰嗦, 第 10 章的标准库会补上工具。

3.4 std.debug.print 与那个古怪的 .{}

打印一行用 std.debug.print,它要两个参数8:

  1. 格式串(format string):也就是上面那个字节切片,里面可以挖占位洞;
  2. 参数元组:一个 .{} 形状的东西,洞里要填的值按顺序放里面。

.{} 是本章最 alien 的语法,原书的解释:「这里没有参数,但我把占位符留着,等你需要时用。」9 它是一个空元组(tuple:不加名字、按位置排列的一组值)—— .{x, y} 就是装了两个值的元组。记住这个形状,第 10 章格式化输出全是它。

3.5 回到主线例子:五行程序的完整旅程

步动作具体产物/现象
①写 main.zig(五行)磁盘上一个文本文件
②zig run main.zigZig 先编译、再立即运行这个可执行文件
③屏幕打印 Hello Zig! 后换行(\n)
④(幕后)编译产物临时目录里的可执行文件;运行完即弃

再把 ② 拆开手动做一遍(原书要求的练习)10:

步动作具体产物/现象
②azig build-exe src/main.zig目录里多出两个文件:main(可执行文件)和 main.o(目标文件)11
②b./main和 zig run 一模一样的输出

解释词:目标文件(object file,.o)。 源代码编译成的机器码先存成 .o, 链接器(把多个 .o 和库缝合成可执行文件的工具)再把它变成 main。 zig run 把这两步藏在背后;手动做一遍的价值,原书说得很准: 等你的项目复杂到要管对象文件、定制构建配置时,「知道每一步是什么」是前提12。

4. 核心原理二:变量三纪律——const、var、undefined

这是本章的正餐。Zig 对变量的规定比多数语言严,严得有理。

4.1 const 是默认值,var 要申请

const x = 1234; 之后,x 锁死,改它就是编译错误:

  $ zig run main.zig
  main.zig:9:7: error: cannot assign to constant
     y += 1;
     ~~^~~~

报错原文照引:cannot assign to constant13。 var 才允许改:var y: i32 = 5678; 然后 y += 1,打印 y = 567914。

书里的态度(作者的立场,不是中立陈述):默认 const,非必要不用 var—— const 让编译器能放心优化,也让读代码的人少猜一层15。 这个立场和第 1 章一脉相承:可变性是一种「隐藏的复杂度」,能不用就不用。

4.2 纪律一:所有变量必须初始化

var x: i32;(只声明不初始化)直接编译不过,报错 expected '=', found ';'16—— Zig 连「声明」这个单独步骤都不存在,声明和初始化必须同写。 这是第 1 章「每个字段必须初始化」安全网的第一块砖:从源头上掐死「用到随机旧数据」。

4.3 纪律二:undefined 是你亲手签的免责书

确实有「现在还没有值」的场景。Zig 给了一个显式逃生口:var x: i32 = undefined;—— 意思是「我不知道这里面现在是什么」17。注意它不是自动初始化, 而是你白纸黑字告诉编译器「这片内存我认了,后果我担」。

4.4 纪律三:Debug 模式用 0xaa 给你插眼

签了免责书之后,Debug 模式(默认档,不额外加参数就是)会往未初始化的内存里 填一个特殊字节图案 0xaa18。走一遍主线例子:

  程序:var x: i32 = undefined; 然后立刻 print
      │
      ├─ Debug 模式编译:Zig 把 x 的 4 个字节填成 aa aa aa aa
      │     (i32 = 32 位整数,占 4 字节;每字节都填 0xaa)
      │
      ├─ 打印:把 0xaaaaaaaa 当成「有符号 32 位整数」解读
      │     = -1431655766   ← 屏幕上的怪数字
      │
      └─ 看到这个数 → 立刻知道「这变量没初始化」

  图说:0xaa 是故意选的好认的图案(10101010, alternating 位)。
  输出 -1431655766 是原书给的实测值。

原书给的运行输出照抄:x = -143165576619。 换变量类型会看到不同的怪数字,但底下永远是 0xaa 填充20。

这个机制为什么聪明(我们的解读):它把「未初始化」从不可见的随机变成 可识别的签名——你不用记住每个类型的未初始化值长什么样, 只要看到「不可能是我写的数」就明白来源。同族的还有 0xdd、0xfd 等填充图案 (分别标记「已释放」「未定义行为保护区」),原书没展开,属于通用知识(补充,不在书里)。

4.5 std.debug:你的调试工具箱

std.debug 是标准库里的调试包,本章只用一个函数 print,但原书列了它深处还有什么: 栈追踪捕获(dumpCurrentStackTrace)、段错误处理器(attachSegfaultHandler)、 可定制的 panic(程序崩溃时执行的函数)21——「更深的留到你基础扎实再碰」。 这个「先立名字、后填内容」的讲法,全书反复出现;我们照单接住。

5. 核心原理三:作用域、遮蔽与命名

5.1 Zig 不允许变量遮蔽(shadowing)

遮蔽的意思是:外层作用域有个 x,内层块里又声明一个同名 x, 内层的把外层的「盖住」。JavaScript 里这是家常便饭;Zig 里直接编译错误22:

  const x = 10;          // 外层 x
  {
      const x = 20;      // 报错:cannot redeclare 'x' in the inner scope
  }

报错照引:cannot redeclare 'x' in the inner scope23。 原书给的理由:防止「同一个名字在不同作用域指不同东西」造成的混乱24。 这又是一个「透明」病例:遮蔽让 x 的含义依赖你在哪一层读它, Zig 选择让名字全局唯一(至少在嵌套关系上)。

判断(我们的,不是书里的): 不许遮蔽在刚学时是束缚,在维护期是保险—— 重构时改一个 x 不用先确认「这一层的 x 是不是那一层的 x」。 但代价也真实存在:像「先读旧值再算新值」这种惯用写法,别的语言靠遮蔽一行写完, Zig 里得另起一个名字,偶尔显得笨。书里只讲了好处;把代价也摆上,判断才完整。 如果错,会错在: 如果团队规模小、代码生命周期短,遮蔽的混乱成本本来就低, 这条纪律的收益会缩水成纯粹的别扭。

5.2 标识符规则与 @"" 逃生口

**标识符(identifier)**就是变量、函数的名字。Zig 的规定:必须以字母或下划线开头25—— var valid_name = 42; 行,var 1invalidName 不行。 非要用怪名字(空格、数字开头),有一个逃生口语法 @"...":

  const @"identifier with spaces" = 42;
  const @"1ExternalLibIdentifier" = 100;

什么时候真需要它?和外部 C 库链接时——那些库的名字可能带空格或以数字开头, @"" 让 Zig 代码能引用它们26。除此之外,原书的建议很直白:别用27。

6. 核心原理四:源码的一致性纪律(UTF-8、LF、空格)

这一节看似琐碎,实则是「透明」在文本层面的延伸:Zig 对源文件本身也立了规矩。

规矩内容出处要点
编码源码必须是 UTF-8;非法字节序列直接编译错误28连注释里也不许藏坏字节
禁用字符ASCII 控制字符(换行 LF、回车 CR、水平制表 HT 之外全禁);Unicode 花样换行符(U+0085、U+2028、U+2029)禁用29「别 sneaking in U+0000」
行尾每行必须以 LF(\n,0x0a)结尾;Windows 的 CRLF 被容忍但不鼓励30最后一个字节建议是 LF
缩进硬制表符被容忍,但用空格31「除非你想起一场格式化战争」
BOMUTF-8 字节序标记只在文件开头被安静忽略,放别处不行32

六道规矩靠 zig fmt 一键全收:它是 Zig 的自动格式化工具, 原书的比方是「私人代码清洁工,扫走你所有的编码罪」33。 .{ }、缩进、行尾,跑一次 zig fmt your_code.zig 全部归位。

值得带走的心态:别的语言把这类事交给「代码风格指南 + code review」, Zig 把它做成了工具——纪律不靠自觉,靠命令。这和第 2 章「让 ZLS 在保存时格式化」 是同一个哲学的两处落地。

7. 核心原理五:zig init —— 项目版流水线

单文件玩够了,这一节升级到「项目」。四步走完:

7.1 创建:zig init 给四个文件

  $ mkdir -p hw && cd hw
  $ zig init
  info: created build.zig
  info: created build.zig.zon
  info: created src/main.zig
  info: created src/root.zig

四个文件各管一件事(原书的总结照收)34:

文件管什么
build.zig项目怎么被编译——构建脚本,本身是一段 Zig 代码
build.zig.zon外部依赖的清单(第 11 章展开)
src/main.zig可执行程序的入口
src/root.zig库的根文件(zig init 默认假定你写库)

7.2 构建:zig build 与 zig-out/

zig build 之后出现 zig-out/ 目录,里面两个子目录35: bin/ 放静态编译好的可执行文件,lib/ 放库(.a 文件——一堆 .o 打包的结果)。 运行 ./zig-out/bin/hw,打印的是 zig init 模板自带的彩蛋:

  All your codebase are belong to us.
  Run `zig build test` to run the tests.

原书特意安抚:这不是 Zig 团队黑进了你的项目,是每个新项目的默认消息36。

7.3 回到全景:单文件 vs 项目

把 §2 那张图补完——两条流水线的关系:

  zig run main.zig          →  临时编译 + 立即运行(图省事)
  zig build-exe main.zig    →  main + main.o(要控制过程)
  zig init + zig build      →  zig-out/bin/ 成品(一个项目的正规入口)

  图说:三条路通向同一个终点,区别只在「谁来管中间产物」。

原书在这一节末尾埋了一句值得记住的话:Zig 的构建系统本身也是 Zig 代码, 所以你学的每一分语言都会变成构建系统的功力——「像一条无限循环的精通回路」37。 第 11 章会兑现这个承诺。

8. 作者的判断与证据

可核的: @import 的签名与「文件即结构体」语义(官方文档,书里引了)5; zig run = 编译+运行10;zig build-exe 产出 main + main.o11; 变量三纪律的报错文本照抄1316;Debug 模式 0xaa 填充与 -1431655766 实测输出1819; UTF-8/LF/空格/BOM 规矩与 zig fmt2833;zig init 四文件、zig-out/bin|lib 结构3435。

作者的立场: 「默认 const」15、「不许遮蔽是为了防混乱」24、 「手动构建的知识将来有用」12——都是经验判断,不是测量结论,但都在 reasonable 范围内; 「每个零件都有用,别嫌 setup 多」37是新手书常见的安慰,真实感受因人而异。

9. 边界与局限

缺什么说明
基本类型没讲原书明说「不无聊地逐个 dissect 基本类型」,只留了一个官方文档链接38。i32、u8 这些名字本章直接用,系统讲要等到第 8、9 章;零基础读者要自己扛一小段
0xaa 只在 Debug 档关键提醒原书说了但没强调:换 ReleaseFast 档,未初始化内存不再被填充 0xaa,读到什么全看运气——「Debug 下的安全网」不是语言保证
zig init 模板细节没拆build.zig 里生成的代码本章一行没讲(只讲了文件分工),「构建脚本即代码」的实感要到第 11 章
错误信息会因版本变脸照抄的报错文本(如 cannot assign to constant)是 0.15 时代的措辞,你机器上可能略有出入
print 的格式化语法没展开{} 占位洞的各种格式({d}、{s}、{x})本章没讲,第 10 章补
20 道章末习题无解析「Make it stick」20 题,答案只有字母39,做错的题没有讲解,等于自己翻书重找

10. 可带走的

本章主线例子,一行走完: 五行 std.debug.print 程序 → zig build-exe 产出 main + main.o → ./main 上屏;var x: i32 = undefined → Debug 模式填 0xaa → 打印出 -1431655766 → 认出「没初始化」→ x = 42 赋值 → 打印 42。

  1. Zig 程序的入口是 pub fn main() void,pub 必须写,否则操作系统进不来;
  2. @ 开头是编译器内建函数;@import 把文件当结构体返回,const std = @import("std") 就是「把标准库绑到 std」;
  3. Zig 没有字符串类型——引号文本是字节切片(起始地址 + 长度),这是「透明」在类型上的落地;
  4. std.debug.print(格式串, .{参数...}),.{} 是空元组占位;
  5. zig run = 编译 + 运行;zig build-exe 手动拆开,产物是可执行文件 + .o 目标文件;
  6. 变量三纪律:默认 const;声明必须同时初始化;undefined 是显式的「后果自负」声明;
  7. Debug 模式把未初始化内存填成 0xaa(i32 下显示为 -1431655766)——看到怪数字先怀疑没初始化;Release 档没有这个保护;
  8. 不许变量遮蔽:内层重用外层名字是编译错误,名字的含义因此不依赖「你在哪一层」;
  9. 源码纪律自动化:UTF-8、LF、空格缩进,全交给 zig fmt,别靠自觉;
  10. zig init 四件套:build.zig(怎么编译)、build.zig.zon(依赖清单)、src/main.zig、src/root.zig;zig build 的成品在 zig-out/bin/。

11. 加深一层:几个原书一句带过、但初学者会卡的点

这一节是我们补的台阶(依据通用知识,标注为补充),原书没有这一层。

11.1 「编译」到底在干什么

源文件是给人看的文本,机器只认机器码(CPU 能直接执行的二进制指令)。 编译就是把文本整体翻译成机器码;链接(link)再把你的机器码和 标准库、启动代码等缝成一个操作系统能加载的文件。 zig build-exe main.zig 一步里其实藏着「编译 → 链接」两小步, main.o 是编译的半成品,main 是链接的成品。 理解这个分工,以后看到「undefined reference to ...」这类链接报错就不会慌: 那是链接器在说「有人调了一个没实现的函数」。

11.2 0xaa 的字节视角走查

主线例子再拆细一格,看清「一个 i32 = 4 个字节」:

  内存地址      字节值     说明
  ─────────────────────────────────────
  x+0           0xaa      Zig 在 Debug 档填入
  x+1           0xaa      Zig 在 Debug 档填入
  x+2           0xaa      Zig 在 Debug 档填入
  x+3           0xaa      Zig 在 Debug 档填入
  ─────────────────────────────────────
  合成 32 位:  0xaaaaaaaa
  按「有符号整数」解读:  -1431655766  ← 屏幕上那个数

  图说:4 个相同的字节,按不同「类型眼镜」看,读出不同的数。
  (i32 = 32 位有符号整数;0xaa 填充是 Zig 行为,各字节值按原书机制描述。)

补充(不在书里,通用知识): 无符号解读 0xaaaaaaaa = 2863311530; 不同类型眼镜读同一块字节的差别,就是第 9 章「类型转换」要讲的全部内容。

11.3 undefined 不是「默认值 0」

常见误会:undefined 听起来像「默认归零」。不是。 它的语义是「这块内存的内容不可预期」——Debug 档凑巧是 0xaa, Release 档就是内存里碰巧剩什么。把 undefined 当 0 用, 等于把「显式签的免责书」误读成「语言给的承诺」。 原书在这一点的表述是对的(「could be anything」17),只是语气轻松, 我们把后果说重一点:这是 undefined behavior(未定义行为,第 1 章 §3.2 解释过)的入口之一。

11.4 格式串的占位洞

{} 是占位洞,填什么值由 .{} 元组按位置提供:print("x = {}, y = {}", .{x, y})。 常用的变形先立名字(细节第 10 章):{d} 明确按十进制整数打印、{s} 按字符串打印、 {x} 按十六进制打印。在洞里写 :>5 之类还能对齐宽度。 为什么默认的 {} 不直接写死十进制?因为 Zig 的类型太多(第 8 章), {} 让「合理的默认打印」由类型自己决定——记住「默认有、可覆盖」即可。

12. 章末二十题:考点地图

原书的「Make it stick」共 20 题,答案是纯字母列表39。我们把考点归类成六组, 方便自查哪组弱:

题号考点弱了回哪节重读
1–2、11–12、14–16main 入口、zig run / build-exe 产物、zig init、对象文件§3、§7
3–6、19@import、std.debug.print、字节切片、.{ }§3
7–10、17–18const/var、初始化纪律、0xaa§4
13、20遮蔽禁令的理由§5.1
—(原书无直接对应)标识符与 @""§5.2
—(原书无直接对应)编码/LF/空格/zig fmt§6

两点观察(我们的):一,二十题的分布暴露了本章真正的重点——变量纪律和构建两步法 占了一半题量,原书认为这就是地基;二,第 17 题(0xaa)和第 10 题几乎重复, 这种重复在「大脑喜欢重复」的教学法里是有意的40。

13. 原文地图

主题原书章原文位置
main 函数四部件Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:28(搜「public function named main」)
空 main 即合法程序Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:39(搜「Nothing happens」)
@import 与 stdChapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:48(搜「linking it to a constant」)
@import 签名与「文件即结构体」Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:63(搜「comptime path」) · text/09-ch03-chapter-3-your-first-zig-program.txt:69(搜「implicitly structs」)
「Zig 没有字符串」Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:73(搜「no strings in Zig」)
切片 = 指针 + 长度Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:82(搜「pointer to an array but with a known length」)
print 要格式串 + 参数Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:97(搜「format string」)
.{} 的解释Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:101(搜「no arguments here」)
zig run = 编译 + 运行Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:108(搜「simply doing two things」)
zig build-exe 与两个产物Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:117(搜「zig build-exe src/main.zig」) · text/09-ch03-chapter-3-your-first-zig-program.txt:123(搜「contains the compiled machine code」)
手动构建的理由Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:137(搜「greater control over the process」)
const 与报错Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:169(搜「const x = 1234」) · text/09-ch03-chapter-3-your-first-zig-program.txt:194(搜「cannot assign to constant」)
var 与可变Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:200(搜「var y: i32 = 5678」)
必须初始化Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:211(搜「all variables must be initialized」) · text/09-ch03-chapter-3-your-first-zig-program.txt:225(搜「expected '='」)
undefined 语义Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:230(搜「no idea what this is yet」)
0xaa 填充Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:343(搜「special byte pattern」) · text/09-ch03-chapter-3-your-first-zig-program.txt:368(搜「-1431655766」)
0xaaaaaaaa 与 i32 解读Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:373(搜「hexadecimal value 0xaaaaaaaa」)
遮蔽禁令Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:264(搜「practically a lifestyle」) · text/09-ch03-chapter-3-your-first-zig-program.txt:274(搜「cannot redeclare」)
标识符规则与 @""Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:291(搜「alphabetic character or an underscore」) · text/09-ch03-chapter-3-your-first-zig-program.txt:300(搜「escape hatch」)
@"" 用于外部库Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:310(搜「external libraries」)
基本类型不展开Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:317(搜「dusty old manual」)
UTF-8 强制Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:413(搜「encoded in UTF-8」)
禁用控制字符Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:421(搜「ASCII control characters」)
LF 行尾Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:429(搜「must end with LF」)
空格缩进Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:441(搜「preferred choice」)
BOM 只在开头Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:444(搜「quietly ignore it」)
zig fmtChapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:449(搜「personal code janitor」)
zig init 四文件Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:473(搜「zig init」) · text/09-ch03-chapter-3-your-first-zig-program.txt:479(搜「created build.zig」)
zig-out 结构Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:498(搜「zig-out/ directory」) · text/09-ch03-chapter-3-your-first-zig-program.txt:502(搜「bundled together」)
模板默认消息Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:515(搜「All your codebase are belong to us」)
四文件分工Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:541(搜「handles how your project gets compiled」)
「无限循环的精通回路」Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:552(搜「infinite feedback loop」)
章末二十题与答案Chapter 3: Your First Zig Programtext/09-ch03-chapter-3-your-first-zig-program.txt:577(搜「Make it stick」) · text/09-ch03-chapter-3-your-first-zig-program.txt:761(搜「Answers」)

Footnotes

  1. 出处:「Chapter 3: Your First Zig Program」第 25–29 段(text/09-ch03-chapter-3-your-first-zig-program.txt:28,搜「public function named main」)。原文:「It's a public function named main, it doesn't take any arguments, and it doesn't return anything—hence, void.」 ↩

  2. 出处:「Chapter 3: Your First Zig Program」第 34–41 段(text/09-ch03-chapter-3-your-first-zig-program.txt:39,搜「Nothing happens」;text/09-ch03-chapter-3-your-first-zig-program.txt:34,搜「already a valid Zig program」)。 ↩

  3. 出处:「Chapter 3: Your First Zig Program」第 43–50 段(text/09-ch03-chapter-3-your-first-zig-program.txt:48,搜「linking it to a constant called std」)。 ↩

  4. 出处:「Chapter 3: Your First Zig Program」第 59–61 段(text/09-ch03-chapter-3-your-first-zig-program.txt:60,搜「built-in function」)。 ↩

  5. 出处:「Chapter 3: Your First Zig Program」第 62–71 段(text/09-ch03-chapter-3-your-first-zig-program.txt:63,搜「comptime path」;text/09-ch03-chapter-3-your-first-zig-program.txt:69,搜「implicitly structs」)。签名为 @import(comptime path: []const u8) type;「adds it to the build if it is not already added」见同段官方引文。 ↩ ↩2

  6. 出处:「Chapter 3: Your First Zig Program」第 73–77 段(text/09-ch03-chapter-3-your-first-zig-program.txt:73,搜「no strings in Zig」)。 ↩

  7. 出处:「Chapter 3: Your First Zig Program」第 81–83 段(text/09-ch03-chapter-3-your-first-zig-program.txt:82,搜「pointer to an array but with a known length」)。这是原书的注释框原文。 ↩

  8. 出处:「Chapter 3: Your First Zig Program」第 90–98 段(text/09-ch03-chapter-3-your-first-zig-program.txt:97,搜「format string」)。 ↩

  9. 出处:「Chapter 3: Your First Zig Program」第 100–102 段(text/09-ch03-chapter-3-your-first-zig-program.txt:101,搜「no arguments here」)。 ↩

  10. 出处:「Chapter 3: Your First Zig Program」第 104–112 段(text/09-ch03-chapter-3-your-first-zig-program.txt:108,搜「simply doing two things」)。 ↩ ↩2

  11. 出处:「Chapter 3: Your First Zig Program」第 115–124 段(text/09-ch03-chapter-3-your-first-zig-program.txt:117,搜「zig build-exe src/main.zig」;text/09-ch03-chapter-3-your-first-zig-program.txt:123,搜「contains the compiled machine code」)。 ↩ ↩2

  12. 出处:「Chapter 3: Your First Zig Program」第 134–144 段(text/09-ch03-chapter-3-your-first-zig-program.txt:137,搜「greater control over the process」)。 ↩ ↩2

  13. 出处:「Chapter 3: Your First Zig Program」第 191–196 段(text/09-ch03-chapter-3-your-first-zig-program.txt:194,搜「cannot assign to constant」)。 ↩ ↩2

  14. 出处:「Chapter 3: Your First Zig Program」第 197–209 段(text/09-ch03-chapter-3-your-first-zig-program.txt:200,搜「var y: i32 = 5678」;text/09-ch03-chapter-3-your-first-zig-program.txt:209,搜「y = 5679」)。 ↩

  15. 出处:「Chapter 3: Your First Zig Program」第 152–168 段(text/09-ch03-chapter-3-your-first-zig-program.txt:153,搜「loves using var everywhere」;text/09-ch03-chapter-3-your-first-zig-program.txt:162,搜「not blowing up your performance」)。 ↩ ↩2

  16. 出处:「Chapter 3: Your First Zig Program」第 211–227 段(text/09-ch03-chapter-3-your-first-zig-program.txt:211,搜「all variables must be initialized」;text/09-ch03-chapter-3-your-first-zig-program.txt:225,搜「expected '='」)。 ↩ ↩2

  17. 出处:「Chapter 3: Your First Zig Program」第 229–231 段(text/09-ch03-chapter-3-your-first-zig-program.txt:230,搜「no idea what this is yet」)。 ↩ ↩2

  18. 出处:「Chapter 3: Your First Zig Program」第 337–363 段(text/09-ch03-chapter-3-your-first-zig-program.txt:343,搜「special byte pattern」;text/09-ch03-chapter-3-your-first-zig-program.txt:347,搜「special 0xaa byte pattern」)。 ↩ ↩2

  19. 出处:「Chapter 3: Your First Zig Program」第 365–374 段(text/09-ch03-chapter-3-your-first-zig-program.txt:368,搜「-1431655766」;text/09-ch03-chapter-3-your-first-zig-program.txt:246,搜「-1431655766」)。 ↩ ↩2

  20. 出处:「Chapter 3: Your First Zig Program」第 371–381 段(text/09-ch03-chapter-3-your-first-zig-program.txt:374,搜「still be filled with the 0xaa pattern」)。 ↩

  21. 出处:「Chapter 3: Your First Zig Program」第 388–402 段(text/09-ch03-chapter-3-your-first-zig-program.txt:396,搜「dumpCurrentStackTrace」;text/09-ch03-chapter-3-your-first-zig-program.txt:399,搜「packed with advanced debugging features」)。 ↩

  22. 出处:「Chapter 3: Your First Zig Program」第 258–266 段(text/09-ch03-chapter-3-your-first-zig-program.txt:264,搜「practically a lifestyle」)。 ↩

  23. 出处:「Chapter 3: Your First Zig Program」第 267–286 段(text/09-ch03-chapter-3-your-first-zig-program.txt:274,搜「cannot redeclare」)。 ↩

  24. 出处:「Chapter 3: Your First Zig Program」第 284–286 段(text/09-ch03-chapter-3-your-first-zig-program.txt:286,搜「prevent the confusion」)。 ↩ ↩2

  25. 出处:「Chapter 3: Your First Zig Program」第 288–291 段(text/09-ch03-chapter-3-your-first-zig-program.txt:291,搜「alphabetic character or an underscore」)。 ↩

  26. 出处:「Chapter 3: Your First Zig Program」第 303–311 段(text/09-ch03-chapter-3-your-first-zig-program.txt:310,搜「external libraries」)。 ↩

  27. 出处:「Chapter 3: Your First Zig Program」第 298–301 段(text/09-ch03-chapter-3-your-first-zig-program.txt:300,搜「escape hatch」)与第 313–314 段(text/09-ch03-chapter-3-your-first-zig-program.txt:313,搜「only use the @」)。 ↩

  28. 出处:「Chapter 3: Your First Zig Program」第 412–416 段(text/09-ch03-chapter-3-your-first-zig-program.txt:413,搜「encoded in UTF-8」)。 ↩ ↩2

  29. 出处:「Chapter 3: Your First Zig Program」第 418–425 段(text/09-ch03-chapter-3-your-first-zig-program.txt:421,搜「ASCII control characters」)。 ↩

  30. 出处:「Chapter 3: Your First Zig Program」第 427–436 段(text/09-ch03-chapter-3-your-first-zig-program.txt:429,搜「must end with LF」;text/09-ch03-chapter-3-your-first-zig-program.txt:434,搜「While Zig tolerates this」)。 ↩

  31. 出处:「Chapter 3: Your First Zig Program」第 438–441 段(text/09-ch03-chapter-3-your-first-zig-program.txt:441,搜「preferred choice」)。 ↩

  32. 出处:「Chapter 3: Your First Zig Program」第 443–445 段(text/09-ch03-chapter-3-your-first-zig-program.txt:444,搜「quietly ignore it」)。 ↩

  33. 出处:「Chapter 3: Your First Zig Program」第 446–451 段(text/09-ch03-chapter-3-your-first-zig-program.txt:449,搜「personal code janitor」)。 ↩ ↩2

  34. 出处:「Chapter 3: Your First Zig Program」第 461–482 段(text/09-ch03-chapter-3-your-first-zig-program.txt:473,搜「zig init」;text/09-ch03-chapter-3-your-first-zig-program.txt:479,搜「created build.zig」)。 ↩ ↩2

  35. 出处:「Chapter 3: Your First Zig Program」第 486–509 段(text/09-ch03-chapter-3-your-first-zig-program.txt:498,搜「zig-out/ directory」;text/09-ch03-chapter-3-your-first-zig-program.txt:502,搜「bundled together」)。 ↩ ↩2

  36. 出处:「Chapter 3: Your First Zig Program」第 511–520 段(text/09-ch03-chapter-3-your-first-zig-program.txt:515,搜「All your codebase are belong to us」;text/09-ch03-chapter-3-your-first-zig-program.txt:518,搜「hasn’t hacked your project」)。 ↩

  37. 出处:「Chapter 3: Your First Zig Program」第 536–554 段(text/09-ch03-chapter-3-your-first-zig-program.txt:552,搜「infinite feedback loop」)。 ↩ ↩2

  38. 出处:「Chapter 3: Your First Zig Program」第 316–323 段(text/09-ch03-chapter-3-your-first-zig-program.txt:317,搜「dusty old manual」)。原书把完整类型清单留给官方文档。 ↩

  39. 出处:「Chapter 3: Your First Zig Program」第 577–781 段(text/09-ch03-chapter-3-your-first-zig-program.txt:577,搜「Make it stick」;text/09-ch03-chapter-3-your-first-zig-program.txt:761,搜「Answers」)。 ↩ ↩2

  40. 出处:「Chapter 1: Safety First」第 90–94 段(text/07-ch01-chapter-1-safety-first.txt:90,搜「Your brain thrives on」)——重复是全书刻意设计的学习法。 ↩

On this page