# 08 · 控制流 0/20 项已确认。当前推进 08-01;本分类尚未完成选择。 本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 ## 08-01 控制结构与值的关系 - [ ] 待讨论 明确条件、匹配、循环中哪些能作为表达式,以及结果能否被忽略;给出允许和不允许的使用位置。 ## 08-02 条件分支的完整规则 - [ ] 待讨论 明确分支写法、结果来源、缺少 `else` 的行为,以及不同出口如何形成结果。结果兼容性依赖【类型系统】。 ## 08-03 条件与真值判断 - [ ] 待讨论 明确条件接受哪些值、是否转换或允许定制,以及不合法条件如何失败。定制机制依赖【对象与类型模型/定制协议】。 ## 08-04 短路与条件求值 - [ ] 待讨论 明确是否支持短路逻辑运算、返回布尔值还是操作数,以及哪些子表达式不会执行。 ## 08-05 循环形式与正常结束 - [ ] 待讨论 明确支持哪些循环、条件何时检查、零次执行和正常耗尽的行为;若循环有值,定义正常结束的结果。 ## 08-06 遍历与迭代协议 - [ ] 待讨论 明确遍历怎样取得下一项、如何识别结束,以及遍历失败和提前退出时的行为。协议形态依赖【定制协议】。 ## 08-07 分支及循环的绑定与作用域 - [ ] 待讨论 明确局部绑定的可见范围、循环变量在各次迭代间的关系、循环后的可见性;检查闭包捕获的交互,依赖【名称与作用域/函数】。 ## 08-08 `break` - [ ] 待讨论 明确合法目标、是否携带值、嵌套时如何选择目标,以及目标不存在或值不合法时的行为。 ## 08-09 `continue` - [ ] 待讨论 明确合法目标、跳转后执行循环的哪个阶段、是否支持指定外层循环,以及非法位置的行为。 ## 08-10 `return` - [ ] 待讨论 明确返回目标、无返回值的行为、函数末尾是否隐式返回,以及在嵌套函数和生成器中的含义。依赖【函数】。 ## 08-11 模式的种类与匹配含义 - [ ] 待讨论 明确支持哪些模式、每种模式如何判断成功,以及不支持的形式如何处理。结构读取与相等判断依赖【对象与类型模型/运算符】。 ## 08-12 匹配顺序与守卫条件 - [ ] 待讨论 明确分支选择顺序、守卫何时执行、失败后是否继续,以及重叠模式和副作用的行为。 ## 08-13 匹配覆盖与失败 - [ ] 待讨论 明确是否要求穷尽、是否允许默认分支、无分支命中的行为,以及不可达分支如何处理。静态检查能力依赖【类型系统】。 ## 08-14 模式中的变量绑定 - [ ] 待讨论 明确绑定与已有值比较如何区分、重复变量与组合模式是否合法,以及失败匹配是否留下绑定。 ## 08-15 生成器的基本控制模型 - [ ] 待讨论 决定是否支持生成器;若支持,明确创建、启动、暂停、恢复和结束,以及如何交付生成值和最终结果。函数调用形式依赖【函数】。 ## 08-16 生成器的提前终止与生命周期 - [ ] 待讨论 若支持生成器,明确主动关闭、内部失败、恢复已结束生成器及重入的行为;明确遗弃生成器时对清理作何保证。依赖【资源管理/内存管理】。 ## 08-17 异常与执行路径 - [ ] 待讨论 明确异常怎样穿过条件、循环、匹配和函数,在哪里可以被接住,以及捕获后从哪里继续。异常表示与匹配规则依赖【异常与错误处理】。 ## 08-18 非正常退出与资源清理 - [ ] 待讨论 明确 `break`、`continue`、`return`、异常和生成器关闭触发哪些清理、执行顺序,以及清理自身再次退出或失败时谁生效。依赖【异常与错误处理/资源管理】。 ## 08-19 控制流边界与非法跨越 - [ ] 待讨论 明确跳转能否跨越函数、闭包、生成器或清理区域,是否支持额外的非局部跳转;给出非法跨越的诊断原则。若其他分类引入异步边界,也在此核对。 ## 08-20 跨分类一致性验收 - [ ] 待讨论 用一组涵盖嵌套分支、循环退出、匹配失败、生成器暂停及清理冲突的例子核对最终规则;所有相关依赖均已解决或明确不适用,没有相互矛盾的决定。 ## 当前问题的方案与语言对照 以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 当前待选的 **08-01** 是:**条件、匹配和循环能否直接产生值?产生的值能否被忽略?** 相关语言提供了几种不同的安排: | 语言 | 规则与小例子 | 取舍及对我们的启发 | |---|---|---| | **Python** | `if`、`match`、`for`、`while` 是语句;另有条件表达式:`x = a if ready else b`。[语句规则](https://docs.python.org/3/reference/compound_stmts.html)、[条件表达式](https://docs.python.org/3/reference/expressions.html#conditional-expressions) | 简短选择可以直接产生值;需要多步计算时,通常回到分支赋值或辅助函数。说明“语句为主”仍可以单独提供条件表达式。 | | **JS/TS** | `if`、`switch` 和循环是语句;条件表达式写成 `const x = ready ? a : b`。TS 在此沿用 JS 的执行语义,并增加静态检查,不是另一套运行时。[ECMAScript 语句](https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html)、[条件表达式](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-conditional-operator)、[TS 类型擦除](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types) | 与 Python 类似:简单选择紧凑,多步分支不直接作为表达式组合。启发是要区分“单独的条件运算符”与“整个分支块都能产生值”。 | | **Go** | `if`、`switch`、`for` 是语句,也没有 `?:`;通常先声明变量,再在分支中赋值。[Go 规范](https://go.dev/ref/spec)、[官方 FAQ](https://go.dev/doc/faq#Does_Go_have_a_ternary_form) | 选择结果与执行步骤使用同一种分支结构,规则较少;代价是简单初始化也可能需要多行。适合参考方案 A。 | | **Rust** | `if`、`match` 是表达式,如 `let x = if ready { a } else { b };`。`loop` 可以用 `break value` 交付结果。[分支规则](https://doc.rust-lang.org/reference/expressions/if-expr.html)、[匹配规则](https://doc.rust-lang.org/reference/expressions/match-expr.html)、[循环规则](https://doc.rust-lang.org/reference/expressions/loop-expr.html) | 多步计算也能直接组合、初始化变量;需要处理各出口的结果兼容性。**但 Rust 的 `while`、`for` 正常结束得到 `()`,不能像 `loop` 那样直接 `break value`。** 表达式化仍然可以区分不同循环。 | 关于“忽略结果”,Rust 明确支持通过表达式语句求值并丢弃结果;这说明**能够产生值,不必意味着必须接住值**。[Rust 表达式语句](https://doc.rust-lang.org/reference/statements.html#expression-statements) 回到我们的三个候选方向: - **A:控制结构主要是语句。** 简单条件是否另设表达式,需要明确;Python/JS 和 Go 在这里就有区别。 - **B:`if`、匹配可以产生值,循环是语句。** 分支计算容易组合,循环无需引入结果规则。 - **C:分支和循环都可以产生值。** 查找、重试可以直接交付结果,但需要定义哪些循环支持、正常耗尽时得到什么。 **我的建议是 B,并允许忽略控制表达式的结果。** 它能让多步分支直接初始化变量,又暂时不引入循环结果的额外规则。这只是建议,尚未记为决定;分支缺少 `else` 等细节仍在 `08-02` 处理。 你更倾向 **A、B、C** 哪一种?对于能够产生值的控制结构,是否允许直接执行并忽略结果? ## 讨论来源 《语言设计 08:控制流》,整理日期 2026-10-28。章节编号沿用原清单。