编程语言研究书库

控制流、循环与其他数字统治形式

控制流、循环与其他数字统治形式

这一章给你指挥代码的全套手势。 三个主干:if 不只判断、还能返回值; switch 强迫你覆盖所有情况,漏一个编译不过;for 循环能同时遍历多个序列, 还自带一个 else 分支。两个进阶:optionals(?T)让「可能没有值」写进类型里, labeled switch 让状态机的跳转写在明面上。每一招都接得住第 1 章那句话: 代码做的就是你读到的。

1. 这一章讲什么

链条位置:第 3 章让程序跑起来,这一章让程序会拐弯。 它也是 Zig 安全哲学的第二次落地(第一次是变量必须初始化): switch 的穷举检查和 optionals 的空值检查,都是「让漏处理在编译期变成错误」。

2. 顶层全景:一张决策地图

  要不要做事?          →  if / else(还能当表达式返回值)
  按值选路?            →  switch(穷举;可带标签做状态机跳转)
  重复做事?            →  for(遍历集合/区间/多序列;可带 else、可带标签)
                         while(条件循环,本章只点到)
  可能没有值?          →  ?T + if 解包 / orelse 默认值

  图说:四问对应四组工具。本章按这个顺序逐个展开。

主线例子沿用原书的数组 items = [4, 5, 3, 4, 0]:一个 for 循环把它从头到尾走一遍, 中间跳过 0、求和、带索引、带切片——全部机制都在这一个输入上走; 状态机部分另起一例(红绿灯),那是 labeled switch 的主场。

3. if:不只是判断,还是表达式

3.1 基本形态:和你知道的一样

if (number > 5) { ... } else { ... }、else if 串联,第 3 章就见过, 没有意外——原书说「可预测是福气」1。

3.2 表达式形态:不用三元运算符

别的语言写一个值按条件取值,用三元运算符 cond ? a : b。 Zig 没有三元运算符;它让 if 直接当表达式用2:

  const result = if (a != b) 47 else 3089;

走一遍:a = 5,b = 4,a != b 为真 → 整个 if...else... 的值是 47 → result = 473。 书里的点评是 Zig 的一贯腔调:「要什么神秘符号,写更清楚的字不好吗」4。

两个纪律(原书的告诫框):别为了炫技把 if 表达式嵌成迷宫;一个代码库里统一一种风格5。 这条告诫在全章反复出现——它其实是 Zig 社区的集体经验,不是这一章特有的。

3.3 与联合类型的配合(预告)

原书预告:if 还能和联合类型(union,第 6 章)配合,区分「成功结果」和「错误」6。 这是第 6 章错误处理的引子,这里只立名字。

4. switch:穷举,且不贯穿

4.1 基本形态

  const day = 3;
  switch (day) {
      1 => print("It's Monday.\n", .{}),
      2 => print("It's Tuesday.\n", .{}),
      3 => print("It's Wednesday.\n", .{}),
      else => print("It's some other day.\n", .{}),
  }

每个分支 值 => 要做的,else 是兜底7。

4.2 两条安全性质(本章承重墙)

性质一:穷举(exhaustive)。 switch 必须覆盖被判断的类型的所有可能值; 漏了,编译错误:switch must handle all possibilities8。 对比:C 和 Go 的 switch 不检查穷尽,逻辑上留个洞编译器也不吭声9。 这条和第 1 章的六张安全网是同一张:把「漏考虑」从运行时事故变成编译时错误。

性质二:默认不贯穿(no fallthrough)。 C/C++/JavaScript 的 switch 有个著名的坑: 匹配了一个 case 之后,如果没有写 break,执行会继续掉进下一个 case。 Zig 取消了贯穿:每个分支自成一体10。想多个值共用一个分支?显式把它们列在一起:

  1, 2, 3 => print("前三天\n", .{}),   // 显式分组,不是「掉了 break」

原书的总结值得照收:穷举 + 不贯穿,让 switch 从「决策工具」升级成 「把安全和清晰直接砌进逻辑」的机制11。

判断(我们的,不是书里的): 这两条性质里,穷举的性价比更高。 它几乎零成本(else 兜底一下就行),却消灭了「新增枚举值时忘了改 switch」这类 维护期最高发的 bug 之一。不贯穿是「治已经治得差不多的病」——现代 C 风格指南 早已要求每个 case 写 break,这个病在认真写的代码里不常发。 如果错,会错在: 对「值域无限」的类型(比如整数),穷举靠 else 兜底, 此时穷举只保证了「你写过 else」,不保证「else 里处理得对」——安全网有边界。

5. for 循环:一个数组走全程

5.1 主线例子:求和,跳过 0

  const items = [_]i32{ 4, 5, 3, 4, 0 };
  var sum: i32 = 0;

  for (items) |value| {
      if (value == 0) {
          continue;        // 跳过这个元素,进入下一轮
      }
      sum += value;
  }
  // sum = 16

逐轮走一遍(这是本章的主线例子,后面每个变体都改它一两行):

轮次value动作sum 之后
14非 0,累加4
25累加9
33累加12
44累加16
50continue,跳过16

输出 The sum is: 1612。语法要点:for (集合) |元素| { ... }—— 竖线里是每一轮绑给循环体的名字。continue 跳过本轮剩余部分,break 直接出循环, 这两个和其他语言一致。

5.2 只遍历一段:切片下标

for (items[0..2]) |value|——[0..2] 是切片语法:从下标 0 开始、到下标 2 之前为止 (含头不含尾,off-by-one 的成年礼)13。走一遍:只碰到 4 和 5,sum = 9。 切片是「视图」不是「拷贝」:它没有复制数据,只是换了个窗口看原数组(第 8 章细讲)。

5.3 要下标:双序列遍历 0..

  for (items, 0..) |_, index| {
      sum += @intCast(index);
  }

0.. 是「从 0 开始的无限区间」,和 items 并排走:每个元素配上它的下标14。 两个名字按顺序对应两个序列:|_, index| 里 _ 表示「这个槽位的值我不想要」 (占位丢弃,是 Zig 的惯用法)。@intCast(index) 把下标类型强转成 i32—— 类型不匹配编译不过,转换必须显式写(第 9 章的类型转换专讲)。

变形记牢一组就够:for (数组, 0..) |值, 下标|。 反过来写 |下标, 值| 是错的——顺序由序列顺序定,这也算一种「透明」: 名字和值的对应关系由位置白纸黑字写出,不靠约定俗成。

5.4 只遍历数字区间

for (0..5) |i| 直接遍历 0 到 415——不需要集合,区间本身就是可遍历的东西。

5.5 一次遍历两个集合

  const items1 = [_]usize{ 1, 2, 3 };
  const items2 = [_]usize{ 4, 5, 6 };
  for (items1, items2) |i, j| {
      total += i + j;
  }
  // total = 21

两个数组锁步(lockstep)前进:(1,4)、(2,5)、(3,6),每对求和16。 边界(原书一句带过但要记住):两个集合必须一样长,不等长会运行时报错17。 (这是 Debug 档的运行时检查在兜底;第 1 章那张四档表在此兑现。)

5.6 循环当表达式:带 else 的 for

Zig 的 for 可以有值,还自带一个 else 分支。语义要记准:

else 在「循环一次都没跑成」或「没 break」时执行;一旦 break 过,else 就不执行。

原书例子走一遍:

  const items = [_]i32{ 1, 3, 4, 5 };
  var sum: i32 = 0;
  var stoppedAtIndex: usize = 0;
  const stoppedEarly = for (0.., items) |i, value| {
      if (@mod(value, 2) == 0) {   // 遇到偶数
          stoppedAtIndex = i;
          break true;              // break 可以带值:整个循环的值
      }
      sum += value;
  } else false;                    // 没遇到偶数才会执行这里

执行轨迹:1 累加(sum=1)、3 累加(sum=4)、4 是偶数 → 记下下标 2、break 带值 true。 输出:Sum of items: 4 和 Stopped at index: 218。

解释词:@mod(value, 2)。 内建函数,取余数;@mod(4, 2) == 0 就是「是偶数」。 这个组合(if 解包 + break 带值 + else)让「查找第一个满足条件的元素」这种高频操作 不需要额外的布尔标志变量——控制流的值本身就是答案。

5.7 标签循环:嵌套的逃生通道

嵌套循环里,内层的 break 只跳出内层。给外层起个名字,就能从内层直接操作外层:

  outer: for (1..6) |_| {          // 外层起名叫 outer
      for (1..6) |_| {
          count += 1;
          break :outer;            // 一次跳出两层
      }
  }
  // count = 1:外层第一轮、内层第一圈就 break 了外层

break :outer 从内层直接跳出外层循环19;对称地,continue :outer 是「跳过外层的下一轮」20。走一遍第二个例子:

  outer: for (1..5) |i| {
      for (1..5) |j| {
          if (i == j) continue :outer;   // i 和 j 相等:跳到外层下一轮
          count += 1;
      }
  }
  // count = 12:i≠j 的 (i,j) 共有 4×3 个

原书对 labeled continue 的点评很诚实:「确保只有你自己看得懂的可靠方法」21—— 威力大、可读性税也高,留给真嵌套深的地方用。

5.8 inline for:编译期展开的循环

inline for 强制在编译期把循环展开:数组有几个元素,循环体就被复制几份, 循环变量变成编译期已知的常量22。原书的例子里,i 在编译期已知, 于是可以用 switch 把 2 映射到类型 f32、4 映射到 i8——值到类型的映射, 只能在编译期做。

代价原书也直说:增加二进制体积、复杂化构建;告诫「除非有 compelling 理由 (和医生的条子),否则别用」23。这是 comptime 世界的第一次露面,第 12 章接它。

5.9 while:本章的缺席者

值得注意:本章正文几乎没有讲 while——只有一段边注说「while 和 for 很像, 仓库里有例子,自己去探索」24。而章末测验第 6 题考的却是 while 的 while (cond) : (续行表达式) 语法,答案选项 : (expression)25。 这是原书的一个小断裂:考的没教。我们用一句话补上(补充,不在书里展开): while (i < 10) : (i += 1) 每轮结束自动执行冒号后的表达式,相当于 for 的「步进」 写在循环头上。深度讲解要等读者自己翻仓库或官方文档。

5.10 循环军规

原书的 best-practice 四条26:保持简单;别过早优化(「相信编译器比你聪明,它多半是」); 写了聪明的(或鲁莽的)代码就留注释解释;认真测试——循环是 off-by-one 和死循环的重灾区。 这些不是 Zig 特有的,但放在 Zig 语境里多了一层意思:Zig 已经把能替你查的都查了 (穷举、越界、长度匹配),剩下的这几条,是它查不了的、归你管的。

6. Optional 类型:?T——把「可能没有」写进类型

6.1 问题从哪来

现实里到处是「可能没有值」:用户没填的输入、没等到的网络数据、没读全的文件。 别的语言的常见结局:空指针异常(null pointer exception)—— 程序在运行时毫无防备地崩掉,而这正是第 1 章说的 C 系崩溃头名死因。

Zig 的解法和「指针默认非空」是同一张网的经纬两面:

  • 指针、值,默认都不能是 null;想可空,类型上必须写明 ? 前缀;
  • 写了 ?,编译器就强迫你处理「没有」的情况,漏处理编译不过。

6.2 ?T 与解包

  const maybeValue: ?i32 = 10;     // 一个「可能是 i32、可能是 null」的值

  if (maybeValue) |value| {        // 有值:解包进 value(此时 value 是普通 i32)
      print("The number is {}\n", .{value});
  } else {                         // 是 null:走这里
      print("No number available.\n", .{});
  }

if (optional) |名字| 是 Zig 的解包语法27:只有确实存在值的那一分支, 才能拿到里面的值——从类型上保证你在「没有」的时候碰不到值。

多个 optional 可以同时查:if (maybeX and maybeY) |x, y|—— 全部非 null 才进 if 分支,并同时解包成 x、y;任何一个为 null 走 else28。 走一遍原书例子:maybeX = 10, maybeY = null → 条件不成立 → 打印 「Cannot compute sum; one of the values is null.」。

6.3 三条安全收益(原书明列)

  1. 不再有空指针崩溃:解包强迫先查再用;
  2. 意图可读:看到 ?T 就知道「这东西可能缺席」,不用翻注释;
  3. 编译期保证:漏处理 null,Zig 编译报错29。

6.4 orelse:给「没有」一个默认值

const n = maybeNumber orelse 0;——是 null 就拿 030。 这是「处理 null 的最懒正确姿势」:适合「缺了就用默认」的语义; 如果「缺了」本身就是需要区分的业务状态,别用 orelse 把它糊掉,回 if 解包。

另两条实践(原书)31:尽早处理 null,别让它顺着调用链传播到深处; 在代码库里写明这个 optional 为什么存在、null 代表什么——类型能强迫你处理, 不能替你解释业务含义。

6.5 遍历装着 optional 的数组

  const items = [_]?i32{ 1, null, 3, null, 5 };
  var sum: i32 = 0;
  for (items) |item| {
      if (item) |value| {
          sum += value;                 // 有值才累加
      } else {
          print("Encountered a null value.\n", .{});
      }
  }
  // sum = 9,中间打印两次 null 提示

逐轮:1→累加 1;null→打印;3→累加 4;null→打印;5→累加 9。 解包语法在循环里原样可用32——「数组里可能有空洞」这个常见现实, 至此有了类型安全的遍历姿势。

判断(我们的,不是书里的): ?T 是第 1 章「指针默认非空」那张安全网的类型面, 两者合起来构成 Zig 对空值问题的完整回答:默认不可空(消灭「想不到的 null」), 显式可空(消灭「忘了查的 null」)。对比 Java 的 Optional 包装类和 Kotlin 的可空类型, Zig 的版本没有运行时对象开销——?i32 和 i32 在机器层面几乎同价 (补充,不在书里,来自 Zig 的可空类型实现惯例:用哨兵值或 padding 表达 null)。 如果错,会错在: 对「值本身合法取值全覆盖」的类型(比如 ?u0 这类边角), 哨兵表达会吃亏;以及 orelse 的滥用会把本该区分的业务状态压成默认值,这是代码评审该盯的。

7. Labeled switch:写在明处的状态机

7.1 它在做什么

普通 switch 判断一次就完;给 switch 加标签后,分支里可以写 continue :标签 下一个值——直接跳到对那个值的匹配分支,相当于把 「循环 + switch + 状态变量」三件套压成一个构造。原书的主例:红绿灯33:

  light: switch (@as(u8, 1)) {
      1 => {
          print("Light is Red. Cars stop.\n", .{});
          continue :light 2;     // 红 → 黄
      },
      2 => {
          print("Light is Yellow. Prepare to stop.\n", .{});
          continue :light 3;     // 黄 → 绿
      },
      3 => {
          print("Light is Green. Cars go.\n", .{});
          continue :light 4;     // 绿 → 行人
      },
      4 => {
          print("Pedestrian crossing activated.\n", .{});
          return;                // 结束
      },
  }

状态轨迹,一步一格:

  入口:值 = 1
    → 分支 1:打印「红灯」,continue :light 2
    → 分支 2:打印「黄灯」,continue :light 3
    → 分支 3:打印「绿灯」,continue :light 4
    → 分支 4:打印「行人通行」,return,结束

  图说:每个状态的「下一个状态」就写在自己分支里,没有状态变量,没有循环。

第二个例子是自动售货机:投币 → 选饮料 → 出货;多一个「取消退款」分支, 同样用 return 收尾34。 vending 例里 4 号分支(取消)没有任何分支跳过去—— 状态机里允许存在「只从外部事件进入」的分支,这在建模真实系统时很自然。

7.2 为什么这样更好(三个理由,前两个是书的,第三个是机制的)

  1. 状态管理:不用外部变量记账,continue :label n 本身就是转移表35;
  2. 清晰:控制流下一个落点白纸黑字,读者不用在循环里追状态变量的变化;
  3. 性能(机制层面):如果 continue 的目标值编译期可知,编译器直接生成 无条件跳转,CPU 的分支预测器(预测下一条指令走向、猜错要付出代价的硬件单元) 对这种完全可预测的跳转零失误;目标是运行期值时,每个 continue 生成独立分支, 预测器能学习「1 后面通常是 2」这类模式,越跑越准36。

7.3 对照组:老式的 while + switch

原书给了等价的旧写法对照37:外面套 while (true),里面 switch, 每个分支手动改状态变量 op = 2; continue;。功能一样,但你要同时盯三个东西: 状态变量、循环、switch。labeled switch 把三个压成一个—— 这就是第 1 章「没有隐藏控制流」的又一次兑现:连状态机的「下一站在哪」都不藏。

7.4 什么时候用它

原书点了三个场景38:状态转移(红绿灯、游戏状态); 分发器/解释器(按输入选动作——编译器、虚拟机内核的典型结构); 多层决策。如果你的代码里有一个 while (true) switch (state) 的三件套, 就是 labeled switch 的候选。

补充(不在书里,来自通用知识): 这种结构在编译器理论里叫 尾调用风格的状态机; labeled switch 还可以 break :标签 值,整个 switch 当表达式 返回值——和 §5.6 的循环表达式是一对。

8. 作者的判断与证据

可核的: if 表达式语法与行为3;switch 穷举报错原文8、不贯穿10; for 的各种形态与输出(16、9、21、4 这些数都能自己跑一遍验证)121618; labeled 循环的 break/continue 语义1920;optionals 解包、and 组合、orelse272830; labeled switch 的两个完整例子3334。

作者的立场: 「别写复杂循环,简单是美德」26——经验之谈,但原书自己给出的 inline for 和多重遍历示例恰恰是「复杂」的;这是教学需要,别当风格指南读。 「inline 循环最好别用」23与「labeled switch 有真实性能收益」36都是合理判断, 但都没有测量数据支撑。

9. 边界与局限

缺什么说明
while 几乎没教正文只有一段边注24,测验却考 while (...) : (expr) 语法25——考的没讲,是原书的一处断裂
循环性能只字未提哪个循环写法快、边界检查多少钱,全章没有数据;「相信编译器」是唯一建议26
labeled switch 的 else 需求穷举要求对 u8 这种宽类型必须有 else 兜底;例子里没写 else 是因为分支已覆盖?——原书例子靠 4 => return 和穷举检查的交互讲得不清,读者照抄前要知道自己类型的值域
union/if 配合是空头支票§3.3 预告「if 处理 union」但本章零展开,全靠第 6 章兑现
optional 的内存布局没讲?i32 在内存里怎么表示(是否多占字节),全章没提;对性能敏感的读者会想知道
习题只到 switch章末 10 题39覆盖 if/switch/for/optional,但 labeled switch、inline for、循环表达式都不在考点里——恰好是本章最有 Zig 特色的三样,考点却绕开了它们

10. 可带走的

本章主线例子,一行走完: items = [4,5,3,4,0] → for (items) |value| → 遇 0 用 continue 跳过 → sum = 16;变体:[0..2] 切片只取前两个(sum=9)、 (items, 0..) 带索引、if...break true...else false 找第一个偶数(停在 2,sum=4)。 状态机:light: switch (1) → 红→黄→绿→行人 → return。

  1. if 是表达式:const r = if (cond) a else b; 取代三元运算符;
  2. switch 穷举:漏分支编译错误 switch must handle all possibilities;else 兜底;
  3. switch 不贯穿:没有「忘了 break 掉下一个 case」这种病;多值共享分支要显式写在一起;
  4. for 的完整形态:for (序列A, 序列B, 0..) |a, b, i|,多序列锁步、必须等长;
  5. 循环可以是表达式:break 值 给出循环的值,else 分支处理「没 break 成」——写「找第一个 X」不再需要标志变量;
  6. 标签循环:outer: + break :outer / continue :outer,嵌套的逃生通道,税是可读性;
  7. inline for 在编译期展开循环,能玩「值映射到类型」的杂技,但最好别用;
  8. optional ?T:默认不可空,可空要显式标;if (opt) |v| 解包、a orelse 默认 兜底、 if (a and b) |x, y| 同时查多个;漏处理 null 编译不过;
  9. labeled switch = 无变量的状态机:continue :标签 下一状态 写在分支里, 编译期目标可优化成无条件跳转,分支预测器友好;
  10. while 的 : (expr) 续行语法本章没教,测验却考——去官方文档或原书仓库补这一课。

11. 原文地图

主题原书章原文位置
if 当表达式Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:89(搜「moonlight as an expression」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:106(搜「47 else 3089」)
if 使用告诫Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:168(搜「intricate if expressions」)
if 与 union(预告)Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:155(搜「error unions」)
switch 穷举与报错Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:178(搜「evaluates all possible cases」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:204(搜「must handle all possibilities」)
不贯穿与显式分组Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:218(搜「no fallthrough by default」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:222(搜「explicitly group them together」)
for 基本遍历(主线例子)Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:256(搜「for (items)
切片只取一段Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:300(搜「items[0..2]」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:300(搜「grabbing elements from index 0」)
带索引的双序列遍历Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:319(搜「for (items, 0..)」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:327(搜「infinite range starting from zero」)
纯区间遍历Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:343(搜「for (0..5)」)
双集合锁步与等长前提Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:365(搜「for (items1, items2)」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:375(搜「in lockstep」)
循环表达式与 elseChapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:391(搜「stoppedEarly = for」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:413(搜「Sum of items: 4」)
标签循环 break/continueChapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:425(搜「outer: for (1..6)」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:428(搜「break :outer」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:454(搜「continue :outer」)
inline forChapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:498(搜「unroll at compile time」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:511(搜「Use inline loops sparingly」)
while 只给边注Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:538(搜「while loops」)
循环军规Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:519(搜「smarter than you」)
?T 定义与解包Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:569(搜「might be present or might be null」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:580(搜「if (maybeValue)
多个 optional 同时查Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:606(搜「maybeX and maybeY」)
optional 三收益Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:627(搜「null pointer dereferencing」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:632(搜「forget to handle the null case」)
orelse 与最佳实践Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:640(搜「maybeNumber orelse 0」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:645(搜「Handle null early」)
遍历 optional 数组Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:665(搜「[_]?i32{ 1, null, 3, null, 5 }」)
红绿灯 labeled switchChapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:710(搜「light: switch」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:713(搜「continue :light 2」)
售货机 labeled switchChapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:752(搜「vending: switch」)
FSM 边注Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:789(搜「Finite State Machine」)
while+switch 对照Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:812(搜「while (true)」)
分支预测与性能Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:851(搜「perfectly predictable branches」)
labeled switch 三场景Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:864(搜「Handling state transitions」)
章末测验Chapter 4: Control Flow, Loops, and Other Forms of Digital Dominationtext/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:892(搜「Testing your knowledge」) · text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:947(搜「execute an expression at the end」)

Footnotes

  1. 出处:「Chapter 4: Control Flow, Loops, and Other Forms of Digital Domination」第 125–148 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:148,搜「predictability is a blessing」)。 ↩

  2. 出处:同章第 87–97 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:89,搜「moonlight as an expression」)。 ↩

  3. 出处:同章第 99–123 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:106,搜「47 else 3089」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:117,搜「5 is, shockingly, not equal to 4」)。 ↩ ↩2

  4. 出处:同章第 121–123 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:122,搜「Why be concise」)。 ↩

  5. 出处:同章第 163–172 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:168,搜「intricate if expressions」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:171,搜「Be consistent」)。 ↩

  6. 出处:同章第 150–161 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:155,搜「error unions」)。 ↩

  7. 出处:同章第 177–202 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:187,搜「switch (day)」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:200,搜「acts as a catch-all」)。 ↩

  8. 出处:同章第 203–205 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:204,搜「must handle all possibilities」)。 ↩ ↩2

  9. 出处:同章第 206–214 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:210,搜「such as C and Go」)。 ↩

  10. 出处:同章第 215–220 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:218,搜「no fallthrough by default」)。 ↩ ↩2

  11. 出处:同章第 226–232 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:226,搜「helps you catch potential bugs early」)。 ↩

  12. 出处:同章第 249–277 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:256,搜「for (items) |value|」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:274,搜「is 16」)。 ↩ ↩2

  13. 出处:同章第 279–303 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:300,搜「items[0..2]」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:300,搜「grabbing elements from index 0」)。 ↩

  14. 出处:同章第 307–333 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:319,搜「for (items, 0..)」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:327,搜「infinite range starting from zero」)。 ↩

  15. 出处:同章第 336–350 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:343,搜「for (0..5)」)。 ↩

  16. 出处:同章第 352–378 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:365,搜「for (items1, items2)」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:377,搜「ends up being 21」)。 ↩ ↩2

  17. 出处:同章第 374–376 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:375,搜「in lockstep」)——「If not, expect fireworks—or at least a runtime error」。 ↩

  18. 出处:同章第 379–414 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:391,搜「stoppedEarly = for」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:413,搜「Sum of items: 4」)。 ↩ ↩2

  19. 出处:同章第 416–442 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:425,搜「outer: for (1..6)」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:428,搜「break :outer」)。 ↩ ↩2

  20. 出处:同章第 444–471 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:454,搜「continue :outer」)。 ↩ ↩2

  21. 出处:同章第 471 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:471,搜「only you understand your code」)。 ↩

  22. 出处:同章第 473–504 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:483,搜「inline for (nums)」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:498,搜「unroll at compile time」)。 ↩

  23. 出处:同章第 506–512 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:511,搜「Use inline loops sparingly」)。 ↩ ↩2

  24. 出处:同章第 536–539 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:538,搜「very similar to for loops」)。 ↩ ↩2

  25. 出处:同章第 947–954 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:947,搜「execute an expression at the end」)。答案 d 见第 954 段。 ↩ ↩2

  26. 出处:同章第 514–524 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:519,搜「smarter than you」)。 ↩ ↩2 ↩3

  27. 出处:同章第 568–593 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:569,搜「might be present or might be null」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:580,搜「if (maybeValue) |value|」)。 ↩ ↩2

  28. 出处:同章第 603–622 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:606,搜「maybeX and maybeY」)。 ↩ ↩2

  29. 出处:同章第 623–634 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:627,搜「null pointer dereferencing」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:632,搜「forget to handle the null case」)。 ↩

  30. 出处:同章第 636–643 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:640,搜「maybeNumber orelse 0」)。 ↩ ↩2

  31. 出处:同章第 644–650 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:645,搜「Handle null early」)。 ↩

  32. 出处:同章第 652–683 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:665,搜「[_]?i32{ 1, null, 3, null, 5 }」)。 ↩

  33. 出处:同章第 690–742 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:710,搜「light: switch」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:713,搜「continue :light 2」)。 ↩ ↩2

  34. 出处:同章第 746–785 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:752,搜「vending: switch」)。 ↩ ↩2

  35. 出处:同章第 797–804 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:799,搜「State management」)。 ↩

  36. 出处:同章第 846–855 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:851,搜「perfectly predictable branches」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:853,搜「distinct conditional branch」)。 ↩ ↩2

  37. 出处:同章第 806–844 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:812,搜「while (true)」;text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:842,搜「more verbose」)。 ↩

  38. 出处:同章第 862–870 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:864,搜「Handling state transitions」)。 ↩

  39. 出处:同章第 892–990 段(text/10-ch04-chapter-4-control-flow-loops-and-other-forms-of-.txt:892,搜「Testing your knowledge」)。 ↩

On this page